协议:Netty通过编程自定义各种协议(netty能够通过codec自己来编码/解码字节流),Tomcat基于Http协议
性能:Tomcat从6.x开始支持nio模式,后续还有APR模式(一种通过jni调用apache网络库的模式,相比于旧的bio模式,并发性能得
到了很大提高),而netty是否比tomcat性能更高,则要取决于netty程序作者的技术实力了。
1.并发高:基于NIO(非阻塞IO)
2.传输快:零拷贝,数据不需要经过经过Socket缓冲区,它在堆内存之外开辟一块内存,数据就直接从IO读到了那块内存中
3.封装好:受到大公司的青睐
io.netty
netty-all
5.0.0.Alpha1
springboot 启动类中启动 DiscardServer(netty启动类),
DiscardServer(netty启动类)再调用 ChildChannelHandler(初始化channel类),
ChildChannelHandler(初始化channel类) 再调用 DiscardServerHandler 类;
DiscardServerHandler 类 再调用service服务;
1.DiscardServer类:
@Component
public class DiscardServer {
@Resource
private ChildChannelHandler childChannelHandler;
public void run(int port) throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
System.out.println("准备运行端口:" + port);
try {
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 128)
.childHandler(childChannelHandler);
//绑定端口,同步等待成功
ChannelFuture f = bootstrap.bind(port).sync();
//等待服务监听端口关闭
f.channel().closeFuture().sync();
} finally {
//退出,释放线程资源
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
}
2.ChildChannelHandler类
@Component
public class ChildChannelHandler extends ChannelInitializer {
@Resource
private DiscardServerHandler discardServerHandler;
@Override
public void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast(discardServerHandler);
}
}
3.DiscardServerHandler类
@Component
@ChannelHandler.Sharable
public class DiscardServerHandler extends ChannelHandlerAdapter{
@Resource
private BaseService baseService;
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg){
try{
ByteBuf in = (ByteBuf) msg;
System.out.println("传输内容是");
System.out.println(in.toString(CharsetUtil.UTF_8));
//这里调用service服务
baseService.baseTest();
}finally {
ReferenceCountUtil.release(msg);
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
// 出现异常就关闭
cause.printStackTrace();
ctx.close();
}
}
4.BaseService接口
public interface BaseService {
/**
* 测试接口
*/
void baseTest();
}
5.接口实现类BaseServiceImpl
@Service
public class BaseServiceImpl implements BaseService {
@Override
public void baseTest() {
System.out.println("成功调用service服务");
}
}
6.springboot启动类
实现CommandLineRunner接口的run方法,在run方法里启动netty服务
@SpringBootApplication
public class FundmodelApplication implements CommandLineRunner{
@Resource
private DiscardServer discardServer;
public static void main(String[] args) {
SpringApplication.run(FundmodelApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
discardServer.run(8089);
}
}
在本地重启一个应用然后在里面写测试类,发送测试数据
@RunWith(SpringRunner.class)
@SpringBootTest
public class DiscardServerTest {
@Test
public void testDiscardServer(){
try {
Socket socket=new Socket("localhost",8089);
OutputStream outputStream = socket.getOutputStream();
PrintWriter printWriter=new PrintWriter(outputStream);
printWriter.write("$tmb00035ET3318/08/22 11:5804029.94,027.25,20.00,20.00$");
printWriter.flush();
socket.shutdownOutput();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
测试结果:
准备运行端口:8089
传输内容是
$tmb00035ET3318/08/22 11:5804029.94,027.25,20.00,20.00$
成功调用service服务
netty与springboot的整合就完成。