
session.setMaxTextMessageBufferSize(单位是字节)
或者
session.setMaxBinaryMessageBufferSize(单位是字节)
来设置数据大小的限制,这样无论是接收数据还是返回数据都能搞定了
但是当我们要使用gateway来转发websocket请求时就不一样了,gateway是使用netty的,所以websocket也是netty的,当websocket请求到网关的时候,网关会创建WebSocketService来转发你的请求,当具体微服务返回webSocket信息是,网关会创建ReactorNettyWebSocketClient来接收你微服务的返回数据来给客户端返回
所以网关中webSocket设置数据大小我们要分别设置服务端接收的大小和客户端返回数据大小
@Bean
//如果有多个的WebSocketService注入到spring容器,优先使用这个
@Primary
public WebSocketService customWebSocketService() {
ReactorNettyRequestUpgradeStrategy requestUpgradeStrategy =new ReactorNettyRequestUpgradeStrategy()
requestUpgradeStrategy.setMaxFramePayloadLength(DEFAULT_FRAME_MAX_SIZE)
return new HandshakeWebSocketService(requestUpgradeStrategy)
}
/**
* 上面的bean是websocket服务端的,负责设置接收数据的大小
* 这个bean是websocket客户端的,负责设置返回数据的大小
* @return
*/
@Bean
@Primary
public ReactorNettyWebSocketClient customReactorNettyWebSocketClient() {
ReactorNettyWebSocketClient reactorNettyWebSocketClient =new ReactorNettyWebSocketClient()
reactorNettyWebSocketClient.setMaxFramePayloadLength(DEFAULT_FRAME_MAX_SIZE)
return reactorNettyWebSocketClient
}
DEFAULT_FRAME_MAX_SIZE自行设置
测试方法采用 mina 和 netty 各实现一个 基于 nio 的EchoServer,测试在不同大小网络报文下的性能表现
测试环境
客户端-服务端:
model name: Intel(R) Core(TM) i5-2320 CPU @ 3.00GHz
cache size: 6144 KB
cpu cores: 4
jdk:1.6.0_30-b12
network:1000Mb
memory: -Xms256m -Xmx256m
Linux: centos 5.7, kernel 2.6.18-274.el5
测试工具:
jmeter v2.4
版本:
mina2.0.7
netty 3.6.2.Final
配置:
mina
io-processor cpu 核数
executor cpu 核数
buffer 初始 buffer 大小,设置为 2048(2k)
netty
boss netty 默认配置 1
worker cpu 核数
executor cpu 核数
其实,从理论上来说, echo 型的应用不配置 executor 业务执行线程池会获得更好的性能和更低的消耗,但考虑在真实业务应用中,真实的业务场景处理通常涉及各种复杂逻辑计算,缓存、数据库、外部接口访问,为避免业务执行延时阻塞 io 线程执行导致吞吐降低,通常都会分离 io 处理线程 和 业务处理线程,因此我们的测试案例中也配置了业务执行线程池考查它们线程池的调度效能。
嗯,本文与其说是ChannelConfig、Attribute源码解析,不如说是对ChannelConfig以及Attribute结构层次的分析。因为这才是它们在Netty中使用到的重要之处。
在 Netty 源码解析 ——— 服务端启动流程 (下) 中说过,当我们在构建NioServerSocketChannel的时候同时会构建一个NioServerSocketChannelConfig对象赋值给NioServerSocketChannel的成员变量config。
而这一个NioServerSocketChannelConfig是当前NioServerSocketChannel配置属性的集合。NioServerSocketChannelConfig主要用于对NioServerSocketChannel相关配置的设置(如,网络的相关参数配置),比如,配置Channel是否为非阻塞、配置连接超时时间等等。
NioServerSocketChannelConfig其实是一个ChannelConfig实例。ChannelConfig表示为一个Channel相关的配置属性的集合。所以NioServerSocketChannelConfig就是针对于NioServerSocketChannel的配置属性的集合。
ChannelConfig是Channel所需的公共配置属性的集合,如,setAllocator(设置用于channel分配buffer的分配器)。而不同类型的网络传输对应的Channel有它们自己特有的配置,因此可以通过扩展ChannelConfig来补充特有的配置,如,ServerSocketChannelConfig是针对基于TCP连接的服务端ServerSocketChannel相关配置属性的集合,它补充了针对TCP服务端所需的特有配置的设置setBacklog、setReuseAddress、setReceiveBufferSize。
DefaultChannelConfig作为ChannelConfig的默认实现,对ChannelConfig中的配置提供了默认值。
接下来,我们来看一个设置ChannelConfig的流程:
serverBootstrap.option(ChannelOption.SO_REUSEADDR, true)
我们可以在启动服务端前通过ServerBootstrap来进行相关配置的设置,该选项配置会在Channel初始化时被获取并设置到Channel中,最终会调用底层ServerSocket.setReuseAddress方法来完成配置的设置。
ServerBootstrap的init()方法:
首先对option和value进行校验,其实就是进行非空校验。
然后判断对应的是哪个常量属性,并进行相应属性的设置。如果传进来的ChannelOption不是已经设定好的常量属性,则会打印一条警告级别的日志,告知这是未知的channel option。
Netty提供ChannelOption的一个主要的功能就是让特定的变量的值给类型化。因为从’ChannelOption<T>option’和’T value’可以看出,我们属性的值类型T,是取决于ChannelOption的泛型的,也就属性值类型是由属性来决定的。
这里,我们可以看到有个ChannelOption类,它允许以类型安全的方式去配置一个ChannelConfig。支持哪一种ChannelOption取决于ChannelConfig的实际的实现并且也可能取决于它所属的传输层的本质。
可见ChannelOption是一个Consant扩展类,Consant是Netty提供的一个单例类,它能安全去通过’==’来进行比较 *** 作。通过ConstantPool进行管理和创建。
常量由一个id和name组成。id:表示分配给常量的唯一数字;name:表示常量的名字。
如上所说,Constant是由ConstantPool来进行管理和创建的,那么ConstantPool又是个什么样的类了?
首先从constants中get这个name对应的常量,如果不存在则调用newConstant()来构建这个常量tempConstant,然后在调用constants.putIfAbsent方法来实现“如果该name没有存在对应的常量,则插入,否则返回该name所对应的常量。(这整个的过程都是原子性的)”,因此我们是根据putIfAbsent方法的返回来判断该name对应的常量是否已经存在于constants中的。如果返回为null,则说明当前创建的tempConstant就为name所对应的常量;否则,将putIfAbsent返回的name已经对应的常量值返回。(注意,因为ConcurrentHashMap不会允许value为null的情况,所以我们可以根据putIfAbsent返回为null则代表该name在此之前并未有对应的常量值)
正如我们前面所说的,这个ConstantPool<ChannelOption<Object>>pool(即,ChannelOption常量池)是ChannelOption的一个私有静态成员属性,用于管理和创建ChannelOption。
这些定义好的ChannelOption常量都已经存储数到ChannelOption的常量池(ConstantPool)中了。
注意,ChannelOption本身并不维护选项值的信息,它只是维护选项名字本身。比如,“public static final ChannelOption<Integer>SO_RCVBUF = valueOf("SO_RCVBUF")” 欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)