如何构建一个基于netty的后端服务器,先打个标题
直接上干货,这个是前奏,比较山寨的实现,大家可先自行看下
https://github.com/xiaotutiger/miyue-music-service/tree/master/miyue-music-service
下面将分析手头上一个项目,运用的技术很全,值得学习,先做一个简单介绍,当然业务部分代码就不讲了。
整个工程采用maven来管理,主要的技术是spring+jedis+netty+disruptor.看这个组合,这个服务器端性能应该很不错。
这个工程又引发我对技术无限热爱 ,哈哈。
这个工程,目前主要是针对一些基于json/xml/text格式的请求,同时也是支持标准手机请求的,当然,可以自定义一些其他格式或者pc端的请求,而且针对不同URI,后面挂了不同的handler,这些可能都是一些web处理的基本思想,只是脱离了常规的web容器或者应用服务器。
xml工具采用xstram来处理,两个字,方便。
json工具采用jackson\不知道和业界出名的fastjson\gson\sf.json有何区别,待鉴定。
客户端的请求,统一继承ClientRequestModel,经过编码统一转化为domainMessage,交由disruptor来处理,其实oop里什么继承,实现,封装思想,大部分都在围绕一个东西在走,一句话,把看似各有棱角的东西如何转化为共同的东西,求同存异啊(比如,水,石头,空气等,如果在这一层,我们没法统一用一个特征来表示,我们可以先把它转化为分子,那是不是可以用同一个东西来表示呢?如何高度抽象封装,这真是一门艺术)。
看这个工程对客户端请求,是如何一步步处理的,message->request->event 交由disruptor来处理,很美妙的思想。在了解这些之前,我们有必要深入学习一下disruptor,很特别的一个框架,宣言很牛逼,中文文档在这里(http://ifeve.com/dissecting-disruptor-whats-so-special/),E文好的同学请移步到这里(http://mechanitis.blogspot.com/2011/06/dissecting-disruptor-whats-so-special.html)
了解disruptor之前,先学习下ringbuffer是如何实现的?
1、ringbuffer的特别之处:
只有一个指针,没有尾指针,基于数组,且不会删除元素,元素会覆盖,充分利用缓存行,减少垃圾回收。
2、如何从ringbuffer读取数据:
------------------------------------------2013-9-9 补充-----------------------------------------------------
下面主要讲一下请求如何处理这块架构吧,其实架构这个东西,说简单一点,就是一种简单可扩展的实现方式,在某些程度上,不要太在意性能。
底层通信建立在netty之上,基本没做任何改动
public class HttpServerPipelineFactory implements ChannelPipelineFactory { private ChannelUpstreamHandler channelUpstreamHandler; public ChannelPipeline getPipeline() throws Exception { // Create a default pipeline implementation. ChannelPipeline pipeline = pipeline(); // Uncomment the following line if you want HTTPS //SSLEngine engine = SecureChatSslContextFactory.getServerContext().createSSLEngine(); //engine.setUseClientMode(false); //pipeline.addLast("ssl", new SslHandler(engine)); pipeline.addLast("decoder", new HttpRequestDecoder()); // Uncomment the following line if you don't want to handle HttpChunks. pipeline.addLast("aggregator", new HttpChunkAggregator(1048576)); pipeline.addLast("encoder", new HttpResponseEncoder()); // Remove the following line if you don't want automatic content compression. pipeline.addLast("deflater", new HttpContentCompressor()); //pipeline.addLast("handler", new HttpRequestHandler()); pipeline.addLast("handler", channelUpstreamHandler); return pipeline; } public void setChannelUpstreamHandler(ChannelUpstreamHandler channelUpstreamHandler) { this.channelUpstreamHandler = channelUpstreamHandler; } }
相关spring配置
<bean id="httpServerPipelineFactory" class="com.yunchao.cm.network.http.HttpServerPipelineFactory"> <property name="channelUpstreamHandler" ref="httpRequestHandler"/> </bean>
<bean id="httpRequestHandler" class="com.yunchao.cm.network.http.HttpRequestHandler"> <property name="urlMaps"> <map> <entry key="/payorder"> <ref bean="payOrderCodecFactory"/> </entry> <entry key="/question"> <ref bean="questionCodecFactory"/> </entry> <entry key="/sms"> <ref bean="smsCodecFactory"/> </entry>
代码太多,不全部贴出来,后面整理一下放到我的github上去。
基如此,我们还是得定义一个handler,继承simpleChannelUpstreamHander,并重写了messageReceied方法,具体在这里。
QueryStringDecoder queryStringDecoder = new QueryStringDecoder(request.getUri()); String url = queryStringDecoder.getPath(); CodecFactory codecFactory = urlMaps.get(url); if (null == codecFactory) { logger.error("unsupported url:{} request.", url); //sendError(ctx, BAD_REQUEST); e.getChannel().close(); return; } //获取cmwap网络中的手机号码 String phone = PhoneUtils.getPhone(request.getHeader("x-up-calling-line-id")); if (request.getMethod().equals(HttpMethod.POST)) { ChannelBuffer content = request.getContent(); String postParams = content.toString(CharsetUtil.UTF_8); logger.debug("request content:{}", postParams); ClientRequestModel model = (ClientRequestModel) codecFactory.decode(postParams); model.setProperty(model.MESSAGE_EVENT_KEY, e); model.setProperty(model.HTTP_REQUEST_KEY, request); model.setProperty(model.HTTP_PHONE_KEY, phone); InetSocketAddress remoteAddress = (InetSocketAddress) e.getRemoteAddress(); model.setProperty(model.IP_KEY, remoteAddress.getAddress().getHostAddress()); logger.info("user request model:{}", model); model.fireSelf();
@Override public DomainMessage fireSelf() { DomainMessage em = new DomainMessage(this); EventUtils.fireEvent(em, "alipayNotifyState"); return em; }
看到这里基本上能够清楚了,是如何把客户端请求包装成ClientRequestModel了,且后面涉及到处理的对象,全部继承它,在整个架构之中,has a 优于 is a,对于客户端netty的一些对象,也是存储在ClientRequestModel中,codec无非也是采用了xml/json/kv,如斯,实现了字节与对象之间的转换。
除此之外,突然想到刚来杭州工作的第一家公司,基于此,采用的架构师servlet充当服务器,因为这是一个公司内部的server,而不是一个平台,采用的数据格式也比较单一,就是xml,但是采用的外部类库也是xstream来处理的,但是整个系统维持的日调用量也是在百万级别,运用的client则是采用httpclient,对于不同请求后面挂的handler,是在容器启动时加载到内存中,其余也没有什么亮点了。
相关推荐
Java基于Netty的websocket微服务架构即时聊天即时通信APP源码,仿微信APP 前端使用Vue3 + TypeScript,后端采用SpringCloud + SpringBoot + Spring Data JPA 。基于 Netty 使用 WebSocket 实现了正常的C/S通信模块。...
网关基于netty 4.0编写。 网关维护与后端服务器的单个静态连接。 当与后端的连接断开时,网关尝试立即重新连接。 多个客户端通道可以使用前端端口连接到网关。 所有请求都通过网关排队到后端服务器。 该实现仅支持在...
使用java开发的游戏项目源码,可用于毕业设计、课程设计、练手学习等
而作为一个即时通信软件必将承受高额的网络IO, 因此本项目采用分布式微服务 + 前后端分离的架构。 前端使用Vue3 + TypeScript,后端采用SpringCloud + SpringBoot + Spring Data JPA 。基于 Netty 使用 WebSocket ...
支持私聊、群聊、离线消息、发送语音、图片、文件、emoji表情等功能支持音视频通话(基于webrtc实现,需要ssl证书)后端采用springboot+netty实现,网页端使用vue,移动端使用uniapp服务器支持集群化部署,每个im-...
使用java开发的游戏项目源码,可用于毕业设计、课程设计、练手学习等
反向代理 通过Netty基于Java NIO的https代理服务器的实现。 这是一个简单的工作原理: 要通过浏览器对其进行测试,我们将需要设置一个虚拟主机名... 为了向后端的Web服务器应用程序提供反向代理,我创建了一个Flask
一款使用Netty+SpringBoot+MUI+HTML5+制作的仿微信的聊天APP,包括聊天,通讯录,发现,个人等模块。 此工程为后端工程,前端工程参照: 安卓版V1.0版 欢迎扫码下载apk测试,或者到前端工程的releases中下载 功能...
03.基于web.socket简单聊天DEM实现-Netty服务器类 04.基于web.socket简单聊天DEMO实现-ChannelHandler实现 05.websocket以及前端代码编写 06.websocket以及前端代码编写测试 07.MUI、HTML5+、HBuilder介绍 07.MUI-01...
Netty的心跳检测机制是一种自定义的、基于应用层的机制。它主要通过定时发送和接收特定的消息(心跳包)来检测连接是否仍然处于活动状态。具体来说,Netty提供了IdleStateHandler类来实现心跳检测。在初始化...
旨在做一个类似于极光推送,小米推送之类的Java程序开源实现。基于Netty + protobuf :backhand_index_pointing_right: fpush监控后台,点击进入演示 :backhand_index_pointing_right: 如果该项目对您有帮忙,您可以...
基于服务器框架。 结帐 根据Apache License 2.0许可。 产品特点 支持0.7 ... 0.9.16 ( netty -socketio 1.6.6)和1.0+ (netty-socketio最新版本)版本 支持XHR轮询传输 支持websocket传输 支持名称空间和房间 ...
使用java开发的游戏项目源码,可用于毕业设计、课程设计、练手学习等
【导读】Northstar盈富量化交易平台,是一个基于springboot+vue开发的、B/S架构、面向个人使用者、能进行实盘交易、策略研究、模拟交易、历史回放、全自动交易的专业交易软件。量化交易系统的功能点作为一个量化交易...
基于 Java Web 项目的 SpringBoot 框架初始化模板,该模板整合了常用的框架,保证大家在此基础上能够快速开发自己的项目,该模板针对于后端启动开发小而精,本项目会由作者持续更新。 业务特性: 1、使用 Undertow ...
xSocket是一个轻量级的基于nio的服务器框架用于开发高性能、可扩展、多线程的服务器。该框架封装了线程处理、异步读/写等方面。 Java多线程程序死锁检查 JCarder JCarder 是一个用来查找多线程应用程序中一些潜在的...
使用介绍:基于SpringBoot + Rpc-Netty-Framework前后端分离、控制与持久层分离的分布式博客系统。 项目亮点: 1. 使用Interceptor + JWT + Hash + Zset 做用户权限双重认证、构建用户热搜词汇排行榜,同时过滤...