京东到家基于Netty的WebSocket应用实践分享(转载)

2024-01-28 14:30

本文主要是介绍京东到家基于Netty的WebSocket应用实践分享(转载),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

转载 https://blog.csdn.net/humn_chou/article/details/80036248

1、前言


在京东到家商家中心系统中,商家提出了要在 Web 端实现自动打印的需求,不再需要人工盯守点击打印,直接打印小票,以节约人工成本。为了满足商家的需求,开发团队决定立即着手实践。本文记录这次从技术选型到动手实践的过程,希望也能给您带来一定的启发。

2、相关文章


新手入门贴:史上最全Web端即时通讯技术原理详解
Web端即时通讯技术盘点:短轮询、Comet、Websocket、SSE
Comet技术详解:基于HTTP长连接的Web端实时通信技术
新手快速入门:WebSocket简明教程
WebSocket详解(一):初步认识WebSocket技术
WebSocket详解(二):技术原理、代码演示和应用案例
WebSocket详解(三):深入WebSocket通信协议细节
WebSocket详解(四):刨根问底HTTP与WebSocket的关系(上篇)
WebSocket详解(五):刨根问底HTTP与WebSocket的关系(下篇)
WebSocket详解(六):刨根问底WebSocket与Socket的关系
MobileIMSDK-Web的网络层框架为何使用的是Socket.io而不是Netty?
socket.io实现消息推送的一点实践及思路
LinkedIn的Web端即时通讯实践:实现单机几十万条长连接
Web端即时通讯技术的发展与WebSocket、Socket.io的技术实践
Web端即时通讯安全:跨站点WebSocket劫持漏洞详解(含示例代码)
开源框架Pomelo实践:搭建Web端高性能分布式IM聊天服务器
使用WebSocket和SSE技术实现Web端消息推送
详解Web端通信方式的演进:从Ajax、JSONP 到 SSE、Websocket
理论联系实际:从零理解WebSocket的通信原理、协议格式、安全性
>>  更多同类文章 ……

3、关于作者


李天翼: 软件开发工程师,任职于达达京东到家后台研发团队,负责订单流程的开发工作。

4、初步思路


关于问题的思考逻辑:

  • 第一种:想到的是可以用ajax来轮询服务端获取最新订单,也就是pull;
  • 第二种:我们是否可以用类似推送的设计来实现,也就是push。

两种思路我们评估其优缺点:

  • ajax方式实现简单,只需要定时从服务端pull数据即可,但也增加了很多次无效的轮询, 无形中增加服务端无效查询;
  • push方式实现稍复杂,需要服务端与PC端保持连接,这就需要建立长连接,最终通过长连接的方式来实现push效果。

经过讨论,我们选择了第二种,订单中心生产出的新订单,通过MQ的方式推送给web端,最终获得一个比较好的用户体验。

5、技术选型


关于长连接方案的选择,我们参考了不少帖子,最终选择使用websocket协议来实现长连接,类似场景如IM,服务端即时推送等都使用了这个协议。

接下来我们比较一下 websocket 的框架,比较主流的有netty、tomcat、 socketIO  三个框架。

基于支持websocket的容器,开发简单,例如tomcat,但在高并发的支持不是很好,连接的时候容易连接断开,还有就是依赖容器。

netty-socketIO是在netty4基础之上做了一层封装,效率如同netty一样,是一个全平台方案,友好的API,京东的logbook也是用了socketIO来传递日志,也是我们的一个备选方案。

netty是业内主流的NIO框架,netty对javaNIO做了封装,让开发者更多关注业务,降低开发成本,很多著名的RPC框架都采用了netty作为传输层,友好的API,功能强大,内置了很多编解码协议,实现websocket协议也是十分方便。

那我们横向比较一下这些框架:
京东到家基于Netty的WebSocket应用实践分享_1.jpeg 

所以在选型方面我们还是定位在socketIO 与 netty 上面,在兼顾扩展性与灵活性的同时,我们也考虑到netty可以提供http的功能,最终我们选择了使用netty,当然socketIO封装了很多功能,也是十分强大,相比较来说netty更适合我们,比较轻量。

6、netty的特性


netty具有异步非阻塞的特性,传统IO是面向流的,NIO是面向缓冲区的,这也是它的非阻塞原因所在。

netty的线程模型如图所示:
京东到家基于Netty的WebSocket应用实践分享_2.jpeg 

这种模型就是我们常说的Reactor模型, boss线程其实是一个独立的NIO线程池,用于接收client请求,默认线程池大小为1,worker线程池用于处理具体的读写操作,默认线程池大小为2*cpu个数

在上述模型中要特别注意ExecutionHandler,ExecutionHandler是运行在worker线程中的,所以 耗时的操作最好在线程池中运行, 比如IO或者计算,不然会影响整个netty的吞吐

7、具体的业务流程


了解了上节这些,我们根据自己的业务设计出流程如下图所示:

  • 步骤(1) web端请求服务端进行注册,注册成功保持长连接;
  • 步骤(2)服务端发送MQ;
  • 步骤(3)netty将收到的消息推送给web端;
  • 步骤(4)web端调用打印控件进行打印,打印控件需提前安装好(打印控件是pc上安装的一个驱动程序,用过JS方式来调用)。

如果调用JS成功,控件将把打印信息放入打印队列,如果不成功,重复步骤(4):
京东到家基于Netty的WebSocket应用实践分享_3.png 

当然现在的结构只是单机版,不满足生产条件,那将来的结构可能会演变成如下图所示:
京东到家基于Netty的WebSocket应用实践分享_4.png 

我们会在服务端与netty之间建立路由层,路由层的主要职责:

  • 第一:收集集群存活信息;
  • 第二:记录落点,就是落在哪一台机器上面;
  • 第三:接收消息与分发消息。

有了这三种能力,我们就可以轻松的指定信息分发策略。这里我们希望使用http协议来路由,所以就需要netty有http短连接接收的能力 ,所以netty整体上需要长短连接两种能力。

8、具体的代码实现


讲了这么多,还是来点干货,下面是部分代码。

netty启动类,我们通过spring来启动netty,因为netty启动会阻塞主线程,所以需要在子线程中来启动netty,下面是启动参数。
京东到家基于Netty的WebSocket应用实践分享_1.jpeg 

接着来写我们的ChannelInitializer,HttpServerCodec为编解码器,WSServerProtocolHandler为websocket协议握手,其中我们更关注业务层面自定义的两个hander,httpRequestHandler,authorizeHandler。
京东到家基于Netty的WebSocket应用实践分享_2.jpeg 

httpRequestHandler的作用是处理url是否合法,接收参数,httpRequestHandler此方法中也可以根据URI来过滤,自定义自己的短连接请求。
京东到家基于Netty的WebSocket应用实践分享_3.jpeg 

authorizeHandler的作用是校验数据是否正确,如果正确会将channel保存到map中,通过map建立起业务ID与通道之间的关系。

校验的过程我们在authorizeHandler中的channelRead展开,如果未通过,直接关闭当前channel,如果通过校验,则通过ctx.fireChannelRead(msg);方法将信息传入下一个handler去处理。

在项目里主要是以传递参数来进行数据校验的,也就是通过URL传参来实现。在httpRequestHandler中我们将URL参数set到channel的attr中,并传递给了下一个handler,也就是authorizeHandler, 所以在authorize方法中我们可以利用get()方法得到参数值,u是经过加密的数据,我们需要在这里进行解密,解密失败,可认为校验失败

当然如果有跨应用的服务,也可以通过Cookie的方式来进行加密串的读写,通过request.getHeader 是可以获取Cookie中的信息,这就看具体业务了,示例代码如下:
京东到家基于Netty的WebSocket应用实践分享_4.jpeg 

这个 map 可以理解为servlet中的session,当有信息需要传送给某个客户端时,我们调用map.get(key)方式的到当前该客户端的channel,调用writeAndFlush方法将信息发送出去,下面举例通过接收MQ消息后的处理逻辑。

接下来有人可能想到,那如果通道关闭了怎么办?map中的channel是不是就失效了呢?那其实我们还需要有一个类似心跳的机制去维护channel,间接的去维护这个map,如果是通道正常关闭,可以通过channelInactive方法来监听,如果是长时间空闲:在项目中我们使用了增加的IdleStateHandler来处理,通过覆盖userEventTriggered 方法来监听空闲channel,当某个channel到达我们设置的超时时间时,netty会回调此方法。

至此,核心部分已经处理完成,剩下的就是通过保存的channel来发送信息给客户端了。

最后在web端,我们采用了 reconnecting-websocket,它是一个小型的 JavaScript 库,封装了 WebSocket API, 提供了在连接断开时自动重连的机制,很能够帮助我们完成断开重连的操作

9、遇到的问题


1)经过测试,在ws的uri后面不能传递参数,不然在netty实现websocket协议握手的时候会出现断开连接的情况,针对这种情况在websocketHandler之前做了一层httpHander过滤,将传递参数放入channel的attr中,然后重写request的uri,并传入下一个管道中,基本上解决这个问题。

2)在读写空闲的时候尽量以发心跳包的方式维护连接,但在客户端由于网络不稳定或者是服务端重启,连接会断开,瞬间有可能接收不到订单消息,为此在客户端需要实现断开重连机制,此问题我们采用 reconnecting-websocket的js框架,此框架扩展了原生websocket的实现,做了断开重连机制,有效的防止断开后不能及时连接。

3)在测试过程中由于控件与小票机的问题,可能会出现打印异常或者小票机没纸的情况,Lodop控件其实是将打印信息放入电脑的打印队列,如果没纸了,小票机会报警,再次放入小票纸,打印机会自动打印队列中的数据。

4)出现调用控件异常偶尔发生,现在处理办法是在js中进行了的try catch 如果失败 进行重试,重试次数自定义,超过重试次数暂不做处理,此处还不太严谨,需要在进行优化。

10、本文小结


通过上面的实践,我们基本已经实现了web端的自动打印,经过长时间的内部测试,服务端与客户端通信稳定,我们将灰度商家做用户体验。

在特定的场景下,选择适当的技术会提高我们的效率,否则会适得其反。选择长连接,大家可以把握三个大原则:

  • 服务端是否需要主动推送数据到客户端以实现控制的效果;
  • 对于实时性的要求是否苛刻;
  • 对于客户端是否需要关注其在线状态的实时变化。

更多关于netty技术我们还在持续地研究中。

(原文链接: https://mp.weixin.qq.com/s/_MTLHfe52eSvc1uXBfuVbg

附录:更多技术文章


有关“为何选择Netty”的11个疑问及解答
开源NIO框架八卦——到底是先有MINA还是先有Netty?
选Netty还是Mina:深入研究与对比(一)
选Netty还是Mina:深入研究与对比(二)
NIO框架入门(一):服务端基于Netty4的UDP双向通信Demo演示
NIO框架入门(二):服务端基于MINA2的UDP双向通信Demo演示
NIO框架入门(三):iOS与MINA2、Netty4的跨平台UDP双向通信实战
NIO框架入门(四):Android与MINA2、Netty4的跨平台UDP双向通信实战
Netty 4.x学习(一):ByteBuf详解
Netty 4.x学习(二):Channel和Pipeline详解
Netty 4.x学习(三):线程模型详解
Apache Mina框架高级篇(一):IoFilter详解
Apache Mina框架高级篇(二):IoHandler详解
MINA2 线程原理总结(含简单测试实例)
Apache MINA2.0 开发指南(中文版)[附件下载]
MINA、Netty的源代码(在线阅读版)已整理发布
解决MINA数据传输中TCP的粘包、缺包问题(有源码)
解决Mina中多个同类型Filter实例共存的问题
实践总结:Netty3.x升级Netty4.x遇到的那些坑(线程篇)
实践总结:Netty3.x VS Netty4.x的线程模型
详解Netty的安全性:原理介绍、代码演示(上篇)
详解Netty的安全性:原理介绍、代码演示(下篇)
详解Netty的优雅退出机制和原理
NIO框架详解:Netty的高性能之道
Twitter:如何使用Netty 4来减少JVM的GC开销(译文)
绝对干货:基于Netty实现海量接入的推送服务技术要点
Netty干货分享:京东京麦的生产级TCP网关技术实践总结
>>  更多同类文章 ……

这篇关于京东到家基于Netty的WebSocket应用实践分享(转载)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/653901

相关文章

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

百度/小米/滴滴/京东,中台架构比较

小米中台建设实践 01 小米的三大中台建设:业务+数据+技术 业务中台--从业务说起 在中台建设中,需要规范化的服务接口、一致整合化的数据、容器化的技术组件以及弹性的基础设施。并结合业务情况,判定是否真的需要中台。 小米参考了业界优秀的案例包括移动中台、数据中台、业务中台、技术中台等,再结合其业务发展历程及业务现状,整理了中台架构的核心方法论,一是企业如何共享服务,二是如何为业务提供便利。

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

hdu1394(线段树点更新的应用)

题意:求一个序列经过一定的操作得到的序列的最小逆序数 这题会用到逆序数的一个性质,在0到n-1这些数字组成的乱序排列,将第一个数字A移到最后一位,得到的逆序数为res-a+(n-a-1) 知道上面的知识点后,可以用暴力来解 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#in

【专题】2024飞行汽车技术全景报告合集PDF分享(附原数据表)

原文链接: https://tecdat.cn/?p=37628 6月16日,小鹏汇天旅航者X2在北京大兴国际机场临空经济区完成首飞,这也是小鹏汇天的产品在京津冀地区进行的首次飞行。小鹏汇天方面还表示,公司准备量产,并计划今年四季度开启预售小鹏汇天分体式飞行汽车,探索分体式飞行汽车城际通勤。阅读原文,获取专题报告合集全文,解锁文末271份飞行汽车相关行业研究报告。 据悉,业内人士对飞行汽车行业

zoj3820(树的直径的应用)

题意:在一颗树上找两个点,使得所有点到选择与其更近的一个点的距离的最大值最小。 思路:如果是选择一个点的话,那么点就是直径的中点。现在考虑两个点的情况,先求树的直径,再把直径最中间的边去掉,再求剩下的两个子树中直径的中点。 代码如下: #include <stdio.h>#include <string.h>#include <algorithm>#include <map>#

【区块链 + 人才服务】可信教育区块链治理系统 | FISCO BCOS应用案例

伴随着区块链技术的不断完善,其在教育信息化中的应用也在持续发展。利用区块链数据共识、不可篡改的特性, 将与教育相关的数据要素在区块链上进行存证确权,在确保数据可信的前提下,促进教育的公平、透明、开放,为教育教学质量提升赋能,实现教育数据的安全共享、高等教育体系的智慧治理。 可信教育区块链治理系统的顶层治理架构由教育部、高校、企业、学生等多方角色共同参与建设、维护,支撑教育资源共享、教学质量评估、