赞
踩
Netty是由JBOSS提供的一个java开源框架。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。Netty 是一个基于NIO的客户,服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户,服务端应用。Netty相当简化和流线化了网络应用的编程开发过程,例如,TCP和UDP的socket服务开发。
Netty简化socket编程,并没有使写出来的Socket效率变低,我写了一个所有都使用默认配置的服务端,模拟最常用的RPC方案,传输协议使用4字节长度加json串的方式来传输,测试服务端的通讯效率,测试结果如下。
从测试结果看,Netty性能是非常高的,在所有使用默认配置的情况下,单台服务器能够达到4万次请求解析,作为RPC框架是足够用的。还有一个有趣的现象是每次都创建连接和重用连接的差别不大,性能损耗对应用层几乎没影响,但是大家如果在应用环境中使用每次新建的情况,一定要进行压测,确认没影响后再使用。
-
public
class
AppNettyServer {
-
-
public
static
void
main
(String[] args)
throws Exception {
-
System.out.print(
"Hello Netty\r\n");
-
-
int
port
=
9090;
-
if (args !=
null && args.length >
0) {
-
try {
-
port = Integer.valueOf(args[
0]);
-
}
catch (NumberFormatException e) {
-
System.out.print(
"Invalid Port, Start Default Port: 9090");
-
}
-
}
-
try {
-
NettyCommandServer
commandServer
=
new
NettyCommandServer();
-
System.out.print(
"Start listen socket, port " + port +
"\r\n");
-
commandServer.bind(port);
-
}
catch (Exception e) {
-
System.out.print(e.getMessage());
-
}
-
}
-
}
-
public
class
NettyCommandServer {
-
-
public
static
InternalLogger
logger
= InternalLoggerFactory.getInstance(NettyCommandServer.class);
-
-
public
void
bind
(int port)
throws Exception {
-
EventLoopGroup
bossGroup
=
new
NioEventLoopGroup();
-
EventLoopGroup
workerGroup
=
new
NioEventLoopGroup();
-
try {
-
ServerBootstrap
serverBootstrap
=
new
ServerBootstrap();
-
serverBootstrap.group(bossGroup, workerGroup);
-
serverBootstrap.channel(NioServerSocketChannel.class);
-
serverBootstrap.option(ChannelOption.SO_BACKLOG,
1024);
-
serverBootstrap.handler(
new
LoggingHandler());
-
serverBootstrap.childHandler(
new
NettyChannelHandler());
-
ChannelFuture
channelFuture
= serverBootstrap.bind(port).sync();
-
channelFuture.channel().closeFuture().sync();
-
}
finally {
-
bossGroup.shutdownGracefully();
-
workerGroup.shutdownGracefully();
-
}
-
}
-
-
private
class
NettyChannelHandler
extends
ChannelInitializer<SocketChannel> {
-
-
@Override
-
protected
void
initChannel
(SocketChannel socketChannel)
-
throws Exception {
-
socketChannel.pipeline().addLast(
new
LengthFieldBasedFrameDecoder(ByteOrder.BIG_ENDIAN,
64 *
1024,
0,
4,
0,
4,
true));
-
socketChannel.pipeline().addLast(
new
StringDecoder(Charset.forName(
"UTF-8")));
-
socketChannel.pipeline().addLast(
new
NettyCommandHandler());
-
}
-
}
-
}
-
public
class
NettyCommandHandler
extends
ChannelHandlerAdapter {
-
private
int
counter
=
0;
-
-
@Override
-
public
void
channelRead
(ChannelHandlerContext ctx, Object msg) {
-
try {
-
String
body
= (String) msg;
-
JsonDataObject
request
= JsonUtil.fromJson(body, JsonDataObject.class);
-
-
counter = counter +
1;
-
JsonDataObject
response
=
new
JsonDataObject();
-
response.setCode(
0);
-
response.setMsg(
"Success");
-
response.setData(counter+
"");
-
String
respJson
= JsonUtil.toJson(response);
-
-
byte[] respUtf8 = respJson.getBytes(
"UTF-8");
-
int
respLength
= respUtf8.length;
-
ByteBuf
respLengthBuf
= PooledByteBufAllocator.DEFAULT.buffer(
4);
-
respLengthBuf.writeInt(respLength);
-
respLengthBuf.order(ByteOrder.BIG_ENDIAN);
-
ctx.write(respLengthBuf);
-
ByteBuf
resp
= PooledByteBufAllocator.DEFAULT.buffer(respUtf8.length);
-
resp.writeBytes(respUtf8);
-
ctx.write(resp);
-
}
catch (Exception e) {
-
NettyCommandServer.logger.error(e.getMessage() +
"\r\n");
-
StringWriter
sw
=
new
StringWriter();
-
PrintWriter
pw
=
new
PrintWriter(sw);
-
e.printStackTrace(pw);
-
pw.flush();
-
sw.flush();
-
NettyCommandServer.logger.error(sw.toString());
-
}
-
}
-
-
@Override
-
public
void
channelReadComplete
(ChannelHandlerContext ctx) {
-
ctx.flush();
-
}
-
-
@Override
-
public
void
exceptionCaught
(ChannelHandlerContext ctx, Throwable cause) {
-
ctx.close();
-
}
-
}
-
public
class
SocketClient :
Object
-
{
-
private TcpClient tcpClient;
-
-
public SocketClient()
-
{
-
tcpClient =
new TcpClient();
-
tcpClient.Client.Blocking =
true;
-
}
-
-
public void Connect(string host, int port)
-
{
-
tcpClient.Connect(host, port);
-
}
-
-
public void Disconnect()
-
{
-
tcpClient.Close();
-
}
-
-
public string SendJson(string json)
-
{
-
byte[] bufferUTF8 = Encoding.UTF8.GetBytes(json);
-
int jsonLength = System.Net.IPAddress.HostToNetworkOrder(bufferUTF8.Length);
//转换为网络字节顺序,大头结构
-
byte[] bufferLength = BitConverter.GetBytes(jsonLength);
-
tcpClient.Client.Send(bufferLength,
0, bufferLength.Length, SocketFlags.None);
//发送4字节长度
-
tcpClient.Client.Send(bufferUTF8,
0, bufferUTF8.Length, SocketFlags.None);
//发送Json串内容
-
-
byte[] bufferRecvLength =
new
byte[
sizeof(
int)];
-
tcpClient.Client.Receive(bufferRecvLength,
sizeof(
int), SocketFlags.None);
//获取长度
-
int recvLength = BitConverter.ToInt32(bufferRecvLength,
0);
-
recvLength = System.Net.IPAddress.NetworkToHostOrder(recvLength);
//转为本地字节顺序
-
byte[] bufferRecvUtf8 =
new
byte[recvLength];
-
tcpClient.Client.Receive(bufferRecvUtf8, recvLength, SocketFlags.None);
-
string recvCommand = Encoding.UTF8.GetString(bufferRecvUtf8,
0, recvLength);
-
return recvCommand;
-
}
-
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。