代码示例:
// 服务提供者协议配置
ProtocolConfig protocol = new ProtocolConfig();
// 协议名称
protocol.setName("dubbo");
//启动dubbo server的端口
protocol.setPort(20880);
// 服务提供方最大可接受连接数 ,0=>不限制
protocol.setAccepts(0);
// dispatcher=>协议的消息派发方式
protocol.setDispatcher("direct");
// 服务线程池大小,默认线程数200
protocol.setThreads(200);
// 线程池类型
protocol.setThreadpool("fixed");
name:
选择默认的dubbo协议(内部使用netty4),走长连接,适合小数据高并发类型.
Accepts:
服务提供方最大可接受连接数,默认为0,不限制最大连接数
threadpool:
默认是选择fixed线程池,从游戏架构上放弃线程池选择,原因查看 dispatcher
Threads:
META-INF下面SPI配置:
fixed=org.apache.dubbo.common.threadpool.support.fixed.FixedThreadPool
cached=org.apache.dubbo.common.threadpool.support.cached.CachedThreadPool
limited=org.apache.dubbo.common.threadpool.support.limited.LimitedThreadPool
eager=org.apache.dubbo.common.threadpool.support.eager.EagerThreadPool
-
fixed 固定大小线程池,启动时建立线程,不关闭,一直持有。(缺省)
-
cached 缓存线程池,空闲一分钟自动删除,需要时重建。
-
limited 可伸缩线程池,但池中的线程数只会增长不会收缩。(为避免收缩时突然来了大流量引起的性能问题)。
-
eager eager与cached类型线程池不同的一点是,提交任务后,线程优先于队列,默认的提交流程是如果线程数达到核心线程数后,新提交的任务是首先进入队列,但eager是优先创建线程来执行
默认线程数200,此处未选用,原因查看 dispatcher
iothreads:
io线程池大小(为netty工作线程),默认cpu个数+1,可在默认数量上修正,具体视业务而定
serialization:
序列化方式,可选:fastjson,fst,hessian2,jdk,kryo,protostuff
dispatcher(非常重要):
-
all 所有消息都派发到线程池,包括请求,响应,连接事件,断开事件,心跳等。
-
direct 所有消息都不派发到线程池,全部在 IO 线程上直接执行。
-
message 只有请求响应消息派发到线程池,其它连接断开事件,心跳等消息,直接在 IO 线程上执行。
-
execution 只请求消息派发到线程池,不含响应,响应和其它连接断开事件,心跳等消息,直接在 IO 线程上执行。
-
connection 在 IO 线程上,将连接断开事件放入队列,有序逐个执行,其它消息派发到线程池。
游戏服和http服务器有一定区别,主要在于短连接maxThreads的大小比CPU核心数量要大很多,这是因为,处理请求的线程真正用于计算的时间可能很少,大多数时间可能在阻塞,如等待数据库返回数据、等待硬盘读写数据等。因此,在某一时刻,只有少数的线程真正的在使用物理CPU,大多数线程都在等待;因此线程数远大于物理核心数才是合理的,这里的http服务器逻辑是同步阻塞,所以线程会很多,但是游戏服是非常排斥阻塞的,所以这里放弃内置的fixed线程池,全部分发到netty的IO线程,线程数降到最低.最后也会根据功能在线程总数和切换时间上做一定权衡,争取效率最大化.