Jadual Kandungan
Netty 线程模型
单线程模式
单接收多工作线程模式
多接收多工作线程模式
RPC 业务线程
方案实现
定义线程池接口
实现固定大小线程池
线程池工厂
修改ChannelHandle的channelRead0方法
问题
Rumah Java javaTutorial Netty 线程模型的实例详解

Netty 线程模型的实例详解

Jul 03, 2017 am 11:33 AM
perniagaan bingkai benang

Netty 线程模型

Netty的线程模型主要是基于React,因为考虑到应用场景的不同所以演化出多种版本。

单线程模式

即接收服务请求以及执行IO操作都由一个线程来完成,由于采用的是IO多路复用这类无阻塞IO操作,所以在请求量不大的情况下单线程模式也是可以解决一部分场景问题的。

单接收多工作线程模式

当请求量增大后,原有的一个线程处理所有IO操作变得越来越无法支撑相应的性能指标,所以提到了一个工作线程池的概念,此时接收服务请求还是一个线程,接收请求的线程收到请求后会委托给后面的工作线程池,从线程池中取得一个线程去执行用户请求。

多接收多工作线程模式

当请求量进一步增大后,单一的接收服务请求的线程无法处理所有客户端的连接,所以将接收服务请求的也扩展成线程池,由多个线程同时负责接收客户端的连接。

RPC 业务线程

上面提到的都是Netty自身的线程模型,伴随着请求量的增长而不断发展出来的优化策略。而RPC请求对应用系统来讲最主要还是业务逻辑的处理,而这类业务有可能是计算密集型的也有可以是IO密集型,像大多数应用都伴随着数据库操作,redis或者是连接其它的网络服务等。如果业务请求中有这类耗时的IO操作,推荐将处理业务请求的任务分配给独立的线程池,否则可能会阻塞netty自身的线程。

接收请求线程与工作线程分工

  • 接收请求线程主要负责创建链路,然后将请求委派给工作线程

  • 工作线程负责编码解码读取IO等操作

方案实现

目前我实现的RPC是采用多接收多工作线程模式,在服务端是这样绑定端口的:

public void bind(ServiceConfig serviceConfig) {EventLoopGroup bossGroup = new NioEventLoopGroup();EventLoopGroup workerGroup = new NioEventLoopGroup();try {ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(this.rpcServerInitializer)
                    .childOption(ChannelOption.SO_KEEPALIVE,true)
            ;try {ChannelFuture channelFuture = bootstrap.bind(serviceConfig.getHost(),serviceConfig.getPort()).sync();//...channelFuture.channel().closeFuture().sync();


            } catch (InterruptedException e) {throw new RpcException(e);
            }
        }finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
Salin selepas log masuk

boosGroup就是一组用来接收服务请求的
workerGroup就是一组具体负责IO操作的

增加业务线程只需要将handle的操作进一步委派给线程池即可,这里为了扩展所以需要定义接口:

定义线程池接口

public interface RpcThreadPool {Executor getExecutor(int threadSize,int queues);
}
Salin selepas log masuk

实现固定大小线程池

参考了dubbo线程池

@Qualifier("fixedRpcThreadPool")@Componentpublic class FixedRpcThreadPool implements RpcThreadPool {private Executor executor;@Overridepublic Executor getExecutor(int threadSize,int queues) {if(null==executor) {synchronized (this) {if(null==executor) {
                    executor= new ThreadPoolExecutor(threadSize, threadSize, 0L, TimeUnit.MILLISECONDS,
                            queues == 0 ? new SynchronousQueue<Runnable>() :(queues < 0 ? new LinkedBlockingQueue<Runnable>(): new LinkedBlockingQueue<Runnable>(queues)),new RejectedExecutionHandler() {@Overridepublic void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {                                   //...}
                            });
                }
            }
        }return executor;
    }
}
Salin selepas log masuk

小插曲:
记的有一次一朋友突然问java 线程池中的那个coreSize是什么意思?我顿时短路了,因平时也不怎么写多线程,想到平时用的比较多的数据库线程池,里面的参数倒是印象比较深,但就是想不起来有个coreSize。后来才又仔细看了下线程池的一些参数。现在借这个机会又可以多多再看看,以免再次短路。

线程池工厂

当有多个线程池实现时,通过线程池名称来动态选择线程池。

@Componentpublic class RpcThreadPoolFactory {@Autowiredprivate Map<String,RpcThreadPool> rpcThreadPoolMap;public RpcThreadPool getThreadPool(String threadPoolName){return this.rpcThreadPoolMap.get(threadPoolName);
    }
}
Salin selepas log masuk

修改ChannelHandle的channelRead0方法

将方法体包装成Task交给线程池去执行。

@Overrideprotected void channelRead0(ChannelHandlerContext channelHandlerContext, RpcRequest rpcRequest) {this.executor.execute(new Runnable() {@Overridepublic void run() {RpcInvoker rpcInvoker=RpcServerInvoker.this.buildInvokerChain(RpcServerInvoker.this);RpcResponse response=(RpcResponse) rpcInvoker.invoke(RpcServerInvoker.this.buildRpcInvocation(rpcRequest));
            channelHandlerContext.writeAndFlush(response);
        }
    });
}
Salin selepas log masuk

问题

目前缺乏压测,所以暂时没有明确的数据对比。

Atas ialah kandungan terperinci Netty 线程模型的实例详解. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Bagaimana untuk menilai keberkesanan kos sokongan komersial untuk rangka kerja Java Bagaimana untuk menilai keberkesanan kos sokongan komersial untuk rangka kerja Java Jun 05, 2024 pm 05:25 PM

Menilai kos/prestasi sokongan komersial untuk rangka kerja Java melibatkan langkah-langkah berikut: Tentukan tahap jaminan yang diperlukan dan jaminan perjanjian tahap perkhidmatan (SLA). Pengalaman dan kepakaran pasukan sokongan penyelidikan. Pertimbangkan perkhidmatan tambahan seperti peningkatan, penyelesaian masalah dan pengoptimuman prestasi. Timbang kos sokongan perniagaan terhadap pengurangan risiko dan peningkatan kecekapan.

Bagaimanakah pilihan rangka kerja PHP yang ringan mempengaruhi prestasi aplikasi? Bagaimanakah pilihan rangka kerja PHP yang ringan mempengaruhi prestasi aplikasi? Jun 06, 2024 am 10:53 AM

Rangka kerja PHP yang ringan meningkatkan prestasi aplikasi melalui saiz kecil dan penggunaan sumber yang rendah. Ciri-cirinya termasuk: saiz kecil, permulaan pantas, penggunaan memori yang rendah, kelajuan dan daya tindak balas yang dipertingkatkan, dan penggunaan sumber yang dikurangkan: SlimFramework mencipta API REST, hanya 500KB, responsif yang tinggi dan daya pemprosesan yang tinggi.

Bagaimanakah keluk pembelajaran rangka kerja PHP berbanding rangka kerja bahasa lain? Bagaimanakah keluk pembelajaran rangka kerja PHP berbanding rangka kerja bahasa lain? Jun 06, 2024 pm 12:41 PM

Keluk pembelajaran rangka kerja PHP bergantung pada kecekapan bahasa, kerumitan rangka kerja, kualiti dokumentasi dan sokongan komuniti. Keluk pembelajaran rangka kerja PHP adalah lebih tinggi jika dibandingkan dengan rangka kerja Python dan lebih rendah jika dibandingkan dengan rangka kerja Ruby. Berbanding dengan rangka kerja Java, rangka kerja PHP mempunyai keluk pembelajaran yang sederhana tetapi masa yang lebih singkat untuk bermula.

Perbandingan prestasi rangka kerja Java Perbandingan prestasi rangka kerja Java Jun 04, 2024 pm 03:56 PM

Mengikut penanda aras, untuk aplikasi kecil dan berprestasi tinggi, Quarkus (permulaan pantas, memori rendah) atau Micronaut (TechEmpower cemerlang) adalah pilihan yang ideal. SpringBoot sesuai untuk aplikasi bertindan penuh yang besar, tetapi mempunyai masa permulaan dan penggunaan memori yang lebih perlahan.

Amalan terbaik dokumentasi rangka kerja Golang Amalan terbaik dokumentasi rangka kerja Golang Jun 04, 2024 pm 05:00 PM

Menulis dokumentasi yang jelas dan komprehensif adalah penting untuk rangka kerja Golang. Amalan terbaik termasuk mengikut gaya dokumentasi yang ditetapkan, seperti Panduan Gaya Pengekodan Google. Gunakan struktur organisasi yang jelas, termasuk tajuk, subtajuk dan senarai, serta sediakan navigasi. Menyediakan maklumat yang komprehensif dan tepat, termasuk panduan permulaan, rujukan API dan konsep. Gunakan contoh kod untuk menggambarkan konsep dan penggunaan. Pastikan dokumentasi dikemas kini, jejak perubahan dan dokumen ciri baharu. Sediakan sokongan dan sumber komuniti seperti isu dan forum GitHub. Buat contoh praktikal, seperti dokumentasi API.

Bagaimana untuk memilih rangka kerja golang terbaik untuk senario aplikasi yang berbeza Bagaimana untuk memilih rangka kerja golang terbaik untuk senario aplikasi yang berbeza Jun 05, 2024 pm 04:05 PM

Pilih rangka kerja Go terbaik berdasarkan senario aplikasi: pertimbangkan jenis aplikasi, ciri bahasa, keperluan prestasi dan ekosistem. Rangka kerja Common Go: Gin (aplikasi Web), Echo (Perkhidmatan Web), Fiber (daya pemprosesan tinggi), gorm (ORM), fasthttp (kelajuan). Kes praktikal: membina REST API (Fiber) dan berinteraksi dengan pangkalan data (gorm). Pilih rangka kerja: pilih fasthttp untuk prestasi utama, Gin/Echo untuk aplikasi web yang fleksibel, dan gorm untuk interaksi pangkalan data.

Apakah salah faham yang biasa berlaku dalam proses pembelajaran kerangka Golang? Apakah salah faham yang biasa berlaku dalam proses pembelajaran kerangka Golang? Jun 05, 2024 pm 09:59 PM

Terdapat lima salah faham dalam pembelajaran rangka kerja Go: terlalu bergantung pada rangka kerja dan fleksibiliti terhad. Jika anda tidak mengikut konvensyen rangka kerja, kod tersebut akan menjadi sukar untuk dikekalkan. Menggunakan perpustakaan lapuk boleh menyebabkan isu keselamatan dan keserasian. Penggunaan pakej yang berlebihan mengaburkan struktur kod. Mengabaikan pengendalian ralat membawa kepada tingkah laku yang tidak dijangka dan ranap sistem.

Pelan Hala Tuju Pembelajaran Rangka Kerja Java: Amalan Terbaik dalam Domain Berbeza Pelan Hala Tuju Pembelajaran Rangka Kerja Java: Amalan Terbaik dalam Domain Berbeza Jun 05, 2024 pm 08:53 PM

Pelan hala tuju pembelajaran rangka kerja Java untuk bidang yang berbeza: Pembangunan web: SpringBoot dan PlayFramework. Lapisan kegigihan: Hibernate dan JPA. Pengaturcaraan reaktif bahagian pelayan: ReactorCore dan SpringWebFlux. Pengkomputeran masa nyata: ApacheStorm dan ApacheSpark. Pengkomputeran Awan: AWS SDK untuk Java dan Google Cloud Java.

See all articles