# netty-parent **Repository Path**: iikspiral/hdl-parent ## Basic Information - **Project Name**: netty-parent - **Description**: netty+springboot打造高性能TCP+JSON/XML接口 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 14 - **Created**: 2021-07-15 - **Last Updated**: 2021-07-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # hdl-netty #### 介绍 netty+springboot打造高性能TCP+JSON/XML接口 使用tcp协议接口大大的提升了接口性能 #### 软件架构 软件架构说明 SpringBoot2.1.5 + Netty 4.1.37 #### 安装教程 1. 下载源码 2. 启动NettyApp 3. 使用Jemter或其他TCP工具发送JSON/XML流式数据访问接口 #### 使用说明 1. Netty配置几乎都在yml/properties中可灵活配置,详见配置文件说明 ``` 下有 ``` 2、 主要类说明 Netty服务启动类:cn.com.bsfit.netty.server.NettySocketServer 数据接收处理器:cn.com.bsfit.netty.handler.SocketReceiveDataHandler,支持默认可接受最大数据1M,可自行配置 业务逻辑处理器:cn.com.bsfit.netty.handler.SocketRequestHandler,其父类使用模板方法完成固定流程,让业务处理类专注于业务 数据返回处理器:cn.com.bsfit.netty.handler.SocketResponseHandler 请求数据转化为通用格式Map处理类:cn.com.bsfit.netty.req.ReqData2MapFacade 可配置化文件类:cn.com.bsfit.netty.config.properties.BaseNettyServerProperties 3、如需了解更多,请查看源码以及doc文件夹下详细文档<<项目介绍.doc>> **4、使用说明** 1、依赖引入 com.hdl hdl-netty 0.0.1-SNAPSHOT **2、业务接口实现并声明为Bean** ```` /** * 类名 DemoService * 描述 样例,实现接口BusinessService,返回业务逻辑返回的数据 * 默认是返回在body对象中 * 返回格式 { "message": {"head": {}, "body": {}} } * 该这个标签格式可自定义实现 * * @author hedonglin * @version 1.0 * @date 2020/4/27 9:48 */ @Service public class DemoService implements BusinessService { @Override public Map reqHandler(Map reqMap, ReqData2MapFacade reqData2MapFacade) throws Exception { Map data = Maps.newHashMap(); data.put("name", "hedonglin"); // 获取facade中的数据 boolean b = reqData2MapFacade.isJson(); data.put("isJson", b); return BaseResponse.builder().success(data); } /** * 自定义异常返回结果(可重写,不重写返回默认错误数据结构BaseResponse#error方法) * @param errMsg 错误信息 * @return 统一异常返回结果 */ @Override public Map getBaseResponseError(String errMsg) { Map result = Maps.newHashMap(); result.put("code", "500"); result.put("errMsg", errMsg); return result; } } ```` 3、配置文件 ```` ####################################### # Netty Server Config ####################################### netty: server: # netty功能启动开关, 默认为false enable: true # netty 主线程池(接受数据的线程池)大小,默认值为1 bosses: 4 # netty 工作线程池大小,默认值为1 workers: 4 # 数据格式转换线程池大小,默认转换JSON和XML两种格式,大小为2 data-trans-poll-size: 2 # 启动端口 port: 8010 # 启动延时,默认1000ms start-delay-time: 1000 # 接受数据的缓冲区大小配置,单位是字节 recbuf: # 最小值默认1KB min-size: 1024 # 初始值默认为10K initial: 10240 # 最大值默认为1M max-size: 1048576 json-response: # JSON返回是否包含顶层字段(如果有顶层字段该配置才生效),默认是false contains-top: false # JSON返回是否包含Head字段(如果有Head字段该配置才生效),默认是true contains-head: false # JSON返回是否包含Body字段(如果有Body字段该配置才生效),默认是true contains-body: false xml-response: # Xml返回是否包含顶层字段(XML有顶层标签,所以这里只能设置为true),默认是true contains-top: true # 限制支持的顶层字段 top-fields: Message,message # 限制支持的首部字段,与主体部分一段一一对应,默认支持配置Head head-fields: Head,head,HEAD # 限制支持的主体字段,与首部部分一段一一对应,默认支持配置Body body-fields: Body,body,BODY ```` 4、入口程序类编写 ```` package com.hdl.demo; /** * 类名 DemoApplication * 描述 TODO * * @author hedonglin * @version 1.0 * @date 2020/4/27 9:54 */ import cn.com.bsfit.netty.NettyApp; import cn.com.bsfit.netty.config.base.BaseConfigurable; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.Banner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.FilterType; /** * 类名 NettyApp * 描述 主程序启动类 * * @author hedonglin * @version 1.0 * @date 2019/9/29 9:43 */ @Slf4j @EnableAutoConfiguration @ComponentScan(basePackages = {"cn.*", "com.*", "net.*"}, // 不适用默认的过滤器 useDefaultFilters = false, //includeFilters 只扫描指定的类 includeFilters = { // 只有实现了BaseConfigurable接口的类才回被扫描 @ComponentScan.Filter(value = {BaseConfigurable.class}, // 过滤类型为指定的类型,比如某个类 type = FilterType.ASSIGNABLE_TYPE)} , // 不扫描NettyApp.class(重要) excludeFilters = { @ComponentScan.Filter(classes = NettyApp.class) } ) public class DemoApplication { public static void main(String[] args) { try { SpringApplication app = new SpringApplicationBuilder().bannerMode(Banner.Mode.OFF).sources(NettyApp.class).build(); app.run(args); } catch (Exception e) { log.error("请确认已正确配置该应用,请检查是否正确配置"); } } } ```` 5、启动DemoApplication ```` 12:36:12.691 [main] INFO com.hdl.demo.DemoApplication - No active profile set, falling back to default profiles: default 12:36:16.537 [main] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat initialized with port(s): 8080 (http) 12:36:16.559 [main] INFO o.a.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-8080"] 12:36:16.575 [main] INFO o.a.catalina.core.StandardService - Starting service [Tomcat] 12:36:16.576 [main] INFO o.a.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/9.0.19] 12:36:16.754 [main] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext 12:36:16.754 [main] INFO o.s.web.context.ContextLoader - Root WebApplicationContext: initialization completed in 3971 ms 12:36:16.997 [main] INFO c.c.bsfit.netty.utils.SpringBeanUtil - --------------------------------------------------------------------- 12:36:16.997 [main] INFO c.c.bsfit.netty.utils.SpringBeanUtil - ========ApplicationContext配置成功======== 12:36:16.997 [main] INFO c.c.bsfit.netty.utils.SpringBeanUtil - --------------------------------------------------------------------- 12:36:17.443 [main] INFO c.c.b.netty.server.NettySocketServer - netty application starting 12:36:17.446 [main] INFO o.a.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-8080"] 12:36:17.469 [main] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat started on port(s): 8080 (http) with context path '' 12:36:17.474 [main] INFO com.hdl.demo.DemoApplication - Started DemoApplication in 5.645 seconds (JVM running for 7.472) **12:36:18.941 [netty主线程-0] INFO c.c.b.netty.server.NettySocketServer - Socket server bound successfully,the port is 8010** ```` 6、重要配置详解 ```` json-response: # JSON返回是否包含顶层字段(如果有顶层字段该配置才生效),默认是false contains-top: false # JSON返回是否包含Head字段(如果有Head字段该配置才生效),默认是true contains-head: false # JSON返回是否包含Body字段(如果有Body字段该配置才生效),默认是true contains-body: false xml-response: # Xml返回是否包含顶层字段(XML有顶层标签,所以这里只能设置为true),默认是true contains-top: true # 限制支持的顶层字段 top-fields: Message,message # 限制支持的首部字段,与主体部分一段一一对应,默认支持配置Head head-fields: Head,head,HEAD # 限制支持的主体字段,与首部部分一段一一对应,默认支持配置Body body-fields: Body,body,BODY ```` 如果是JSON请求,且需要格式请求和响应格式,如 ```` { "Message": { "Head": { "headKey": "测试头" }, "Body": { "bodyKey": "测试体" } } } ```` Message, Head, Body 都可以后台配置,并且可以使用开关关闭。 使用jmeter发送TCP请求 注意: ```` 1、jmeter默认TCP的编码格式不是UTF-8, 需要在bin/jmeter.properties中修改tcp编码。 2、jmeter发送tcp请求时,需要关闭连接(选中close connection),因为实现的时短连接。 3、如果时XML请求,则必须存在顶层标签 ````