惠而浦:使用Netty和Kafka的微服务

介绍

在上一个博客中 ,我介绍了Netty用作Web服务器。 该示例运行良好……只要需要广播服务器即可。

大多数情况下不是很有用。 更有可能的是,每个客户端仅接收针对其的数据,并保留了特殊情况下的广播,例如“服务器在15分钟内停机!” 关于该特定服务器示例的另一件事是,一切都是独立的。 例如,单片应用程序很好,但是在当今环境中,分布式微服务要好得多。 可伸缩性和可靠性至关重要。

Netty和Kafka在一起很棒。 Netty擅长处理大量客户,Kafka擅长使大量服务协同工作。 结合起来,它们是开发中的最佳选择。 但是,有些“陷阱”可能会使其变得麻烦。 该博客,以及示例微服务/ Netty体系结构和功能全面的代码,将有望帮助减轻烦恼并实现甜味。

第一件事第一

示例代码位于此处 。

有详细的自述文件,描述了设置环境所需的内容。 我试图将需求降到最低,仅Java 8和Maven 。 SLF4J和Logback用于记录日志。 我为Mac OSX和Ubuntu设置了脚本(我在Parallels容器中运行的14.04版是我测试过的脚本),因此如果您在Windows上进行开发,则表示歉意。 该代码全部是Java,并且我在Windows上看到过Kafka教程,因此所有内容都应在此处运行。 Maven构建还应该产生可以启动的目标,因此,在安装Zookeeper / Kafka的时候加一点肘油脂(您可以按照脚本来查看需要哪些设置),手动运行它并不重要。视窗。

注:README.md中所述,该脚本将删除任何现有的Zookeeper / Kafka安装和数据。 如果您已有设置,请不要使用脚本!

安装和配置必备mvn package如果不使用脚本,请运行mvn package如果是,则运行maclocal_run.sh (或linuxlocal_run.sh )。 该脚本将下载Zk / Kafka(如果尚未下载),安装它们,对其进行配置,启动它们,运行mvn package ,启动服务并最终启动服务器。 一旦启动,就不要再想离开shell了,因为它会自动为架构的每个部分弹出新的选项卡。 启动Whirlpool服务器之后,就可以开始了。

我强烈建议创建一个脚本,以在本地安装,配置,构建和启动微服务环境。 创建每个单独的服务是一个很大的痛苦。 如有必要,也可以使用Docker,但我发现只需本地运行所有内容,下载所需的内容就少得多。

作为一个预告片,这里是UI(您也可以从GitHub上的README.md看到它)。

漩涡浴

  • 要添加股票代码,请输入它(即“ GOOG”),然后单击“股票”下的A按钮。 要删除它,请单击X。
  • 要添加一个网站来测试它是打开还是关闭,请键入完全限定的URL(即http://facebook.com ),然后单击“ UpDown”下的A按钮。 要删除它,请单击X。
  • 要添加天气检查,请在中键入城市,州(即“芝加哥,il”),然后单击“城市,州”下的A按钮。 要删除它,请单击X。
  • 由于订阅与每个服务一起存储在内存中,因此订阅在页面刷新甚至登录/注销(具有相同的用户ID)后都不会丢失。 当然,“真实”系统将使用数据库。
  • 订阅每10秒更新一次,因此我不会压倒Yahoo API,因此添加数据后请耐心等待。

建筑

通过这个示例,我试图考虑可能有用的良好通用服务。 我最终选择了股票报价服务,“此网站是否正常运转”服务以及气象服务。 这些中的每一个都独立于各自具有Kafka主题的其他主题运行。

我选择配置Kafka的方式是每个服务使用一个命令主题,每个服务使用一个数据主题。 一切都可能只使用一个全局主题,读者可以决定要处理的内容,但将它们分开可以使内容更加清晰明了。

这是数据如何通过Kafka流动的示意图。 它是通过一个免费的基于Keyhole网络的实用程序Mockola完成的 。 请注意,服务器知道所有主题,但是服务仅知道它们自己的主题。 cmd主题用于将命令发送到服务,而数据主题(在其上没有-cmd主题)用于从服务发送数据。 同样,所有这些都可以在一个bus主题上进行处理,但是通过将它们分离出来,可以更轻松地了解发生了什么。

whirlpool_architecture

服务

现在让我们谈谈服务。 这三者非常相似,因此有一项基本服务可以完成大部分工作。 每个服务都有三个线程,由Java ExecutorService处理。 关于Executor服务的一件好事是,如果出现问题,它将自动重新启动线程。 这有助于弹性。

每个服务通过告诉基类使用什么主题和命令主题来启动自己。 然后,基类启动三个线程:一个用于从cmd主题读取命令,一个用于定期为客户端收集数据,一个用于在数据主题上发送数据。 这些线程使用非阻塞Java并发类ConcurrentLinkedQueueConcurrentHashMap 。 哈希图存储每个用户的订阅集,队列存储准备发送给数据主题的响应。

每个服务的流程是同时工作的三个线程。 阅读器使用Kafka使用者从其命令主题读取命令。 根据命令,添加或删除订阅。 该线程非常笨拙,因为它不要求服务对请求进行任何验证,而只是盲目地将发送给订阅的内容添加进去。 生产代码显然会添加一个调用,以要求服务在允许成功订阅之前验证命令。 创建一个响应以放置主题,然后等待下一个命令。

注意 :关于数据的一些话题。 我使用JSON作为传输格式,但是XML或您想要的其他任何内容也可以使用。 重要的是,每个人都同意数据格式并坚持使用。 通用模块具有POJO类,这些类定义了数据将遵循的协定。 通常对所有消息有用的是时间戳,消息类型和客户端ID。

另一个有用的东西是到期时间戳。 这些示例消息永远存在。 Message类仅查看Message的类型和ID。 服务器使用它来确定需要处理哪种类型的消息以及谁对该消息感兴趣。 没有这些,就很难甚至不可能处理数据。 现在,消息格式可以涉及很多,其中一些格式使用标题和部分来描述复杂的数据。 本示例尝试使所有内容尽可能简单。

净值服务器

让我们一次上一堂课。

NettyHttpFileHandler

此类与以前的博客基本保持不变。 可重用的片段已移至WebSocketHelper类。 该文件的主要用途是提供浏览器要求的文件。

WebSocket助手

可能令人困惑的第一项是类变量clientAttr 。 在Netty Channel中存储数据要求将其附加到AttributeKey 。 这类似于Java并发类中的Atomic实例-它提供​​了数据容器。 我们将存储客户端ID(在本例中为用户名,但也可以轻松地作为会话ID),以便我们确定哪个Channel需要接收消息。

realWriteAndFlush()方法设置适当的标题,内容长度和cookie。 然后,它写入并刷新HTTP响应。 线

channel.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);

告诉Netty这是需要写入客户端的数据的结尾,因此Netty会将其发送出去。

特别说明 :关于cookie的创建,请确保未设置HTTP Only标志。 如果是,则JavaScript无法看到cookie,也不会与WebSocket升级请求一起发送。 这样一来,您就必须创建自己的页面刷新管理和会话管理方法。

关于cookie的另一件事是使用Netty cookie编码器的STRICT版本,因此它将不允许多个具有相同名称的cookie。 我不确定何时允许这种情况发生。

WebSocketMessageHandler

这个类只是定义了一个接口WhirlpoolServerHandler使用交谈的WhirlpoolMessageHandler

WhirlpoolMessageHandler

这是Netty和Kafka之间存在连接的地方。 两个执行器处理一个读取器线程和一个写入器线程。

编写器线程在请求​​队列中查找消息(更多有关这些消息在一分钟内来自何处的信息),并将消息放在适当的Kafka命令主题上。

阅读器线程在Kafka数据主题上查找传入消息,为每个主题查找正确的Channel,然后将消息写入这些主题。

当客户端通过WebSockets发送消息时, WhirlpoolServerHandler将确保已handleMessage()完整的消息,然后调用handleMessage() 。 该方法确定是否为有效消息,然后将请求添加到请求队列中,以便读取器线程可以将其提取并提供给Kafka。

WhirlpoolServerHandler

这节课有一些有趣的事情。 首先,它可以区分HTTP,REST和WebSocket消息之间的区别。 执行此操作的Netty重写方法是channelRead0 。 这是Netty用来告诉我们消息何时到达以及消息是哪种类型的方法。 对于HTTP和REST调用, handleHttpRequest调用handleHttpRequest ,对于handleWebSocketFrame将调用handleWebSocketFrame

如果存在cookie方法,则handleHttpRequest方法handleHttpRequest读取该cookie。 在POST上,它会查找登录和注销信息。 对于登录,它将找出用户名/密码,创建cookie,并防止多次使用相同的名称登录。 所有这些代码将在应用程序的生产版本中添加额外的安全性进行拆分。 要注销,它会查找Channel,清理,关闭它并使cookie过期。

对于WebSocketUpgrade ,它要求Netty处理启动websocket所需的复杂握手。 完成此操作后,会将用户添加到握手期间创建的Channel。 这是用户连接到Channel的地方,如果cookie没有在请求中出现,那将不是一件容易的事。

唯一需要注意的是,该类设置为处理为SPA(单页应用程序)编码的客户端,因为它将所有无法识别的调用重定向到index.html

该类中的其他方法更多用于提供信息,将在高级情况下使用。

漩涡服务器

此类启动Netty服务器并创建通道管道。 它是Netty的一个标准类,它遵循Netty示例。

最后的想法

显然,还有更多的代码可以使用。 每个服务和服务器的多个实例可以同时运行,并且Zk / Kafka可以群集以帮助提高弹性。 一个测试微服务应用程序弹性的强大实用程序是另一个名为TroubleMaker的免费开源Keyhole实用程序。 我还没有机会测试这个示例,但是我很期待这个机会。

我们没有涉及安全性,尽管我以前希望展示Netty与Shiro的集成,但这是一个非常复杂的话题。 我只能说这是有可能的,但是我还没有将所有内容都包裹在脑海中,以致于无法形成一个连贯的博客。

我希望您喜欢该博客并发现有用的代码。 通过博客或Twitter与我联系( @johnwboardman ,在这里我总是很欣赏新的关注)。

翻译自: https://www.javacodegeeks.com/2016/05/whirlpool-microservices-using-netty-kafka.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/354099.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python倒排索引实现_倒排索引原理和实现 - uncle_LLD的个人空间 - OSCHINA - 中文开源技术交流社区...

关于倒排索引搜索引擎通常检索的场景是:给定几个关键词,找出包含关键词的文档。怎么快速找到包含某个关键词的文档就成为搜索的关键。这里我们借助单词——文档矩阵模型,通过这个模型我们可以很方便知道某篇文档包含哪些关键词,某…

Spring RESTful Web服务中的异常处理

1.简介 我们可能已经在Spring中遇到了几种处理RESTful Web服务应用程序中异常的方法。 在本文中,我们将尝试探索可以采取的最佳方法来实现有效的异常处理。 2.问题陈述 让我们创建一个简单的应用程序,该应用程序将在REST URI中标识员工姓名。 如果请求中…

java调python画图_Python Matplotlib plot 绘图

1、绘制x和y点plot()函数用于在图中绘制点(标记)。默认情况下,plot()函数在点到点之间画一条线。该函数具有用于在图中指定点的参数。参数1是一个数组,其中包含x轴上的点。参数2是一个包含y轴上的点的数组。如果需要绘制从(1,3)到(8&#xff…

jms activemq_带有ActiveMQ的JMS

jms activemq带有ActiveMQ的JMS JMS是Java消息服务的缩写,它提供了一种以松散耦合,灵活的方式集成应用程序的机制。 JMS以存储和转发的方式跨应用程序异步传递数据。 应用程序通过充当中介的MOM(面向消息的中间件)进行通信&#x…

【EMV L2】SDA静态数据认证处理流程

【静态数据认证】 静态数据认证处理过程中,卡片没有执行任何处理,终端执行的处理流程:1、认证中心公钥的获取终端使用卡片上的认证中心公钥索引(PKI)【TAG:8F,Certification Authority Public K…

java取邮箱前缀_java抓取网页或文件中的邮箱号码

java抓取网页或文件中的邮箱号码发布时间:2020-10-18 08:58:32来源:脚本之家阅读:69作者:java大渣渣本文实例为大家分享了java抓取邮箱号码的具体代码,供大家参考,具体内容如下java抓取文件中邮箱号码的具体…

java btrace_BTrace:Java开发人员工具箱中的隐藏宝石

java btrace这篇文章是关于BTrace的 ,我正在考虑将其作为Java开发人员的隐藏宝藏。 BTrace是用于Java平台的安全,动态跟踪工具。 BTrace可用于动态跟踪正在运行的Java程序(类似于DTrace,适用于OpenSolaris应用程序和OS&#xff09…

xampp浏览php出现乱码,dvwa+xampp搭建显示乱码的问题及解决方案

如图,dvwa显示乱码,解决办法有两个:1、方法一是,临时解决办法,也就是每次都得手动修改:利用浏览器的编码修改2、方法二是:永久方案,那就是修改dvwa的配置文件,修改默认编…

HotSpot的-XshowSettings标志的简单性和价值

一个方便的HotSpot JVM标志 ( 选项为Java启动 java )是-XshowSettings选项。 Oracle Java启动器描述页面中对此选项进行了如下描述 : -XshowSettings : category显示设置并继续。 该选项的可能类别参数包括: all显示所…

Python验证码简单实现(数字和大写字母组成的4位验证码)

#数字和英文大写字母的4位随机数 def checkcode(): #def 定义方法 checkcode() 方法名()import random # 导入包checkcode ""string range(0,4)for i in string:current random.randrange(0,3) #randrange随机数 参数1<随机数<参数2if current ! i:temp …

php haystack,haystack(示例代码)

1、haystack简介Haystack是django的开源全文搜索框架(全文检索不同于特定字段的模糊查询&#xff0c;使用全文检索的效率更高 )&#xff0c;该框架支持Solr,Elasticsearch,Whoosh, Xapian&#xff0c;搜索引擎它是一个可插拔的后端(很像Django的数据库层)&#xff0c;所以几乎你…

fopen php 乱码,如何解决php fgets读取文件乱码的问题

如何解决php fgets读取文件乱码的问题,文件,乱码,简体中文,记事本,页面如何解决php fgets读取文件乱码的问题易采站长站&#xff0c;站长之家为您整理了如何解决php fgets读取文件乱码的问题的相关内容。php fgets乱码的解决办法&#xff1a;首先依次点击“菜单修改->页面属…

一致性哈希算法原理分析及实现

一致性哈希算法常用于负载均衡中要求资源被均匀的分布到所有节点上&#xff0c;并且对资源的请求能快速路由到对应的节点上。具体的举两个场景的例子&#xff1a; 1、MemCache集群&#xff0c;要求存储各种数据均匀的存到集群中的各个节点上&#xff0c;访问这些数据时能快速的…

jsf集成spring_JSF – PrimeFaces和Hibernate集成项目

jsf集成spring本文介绍了如何使用JSF&#xff0c;PrimeFaces和Hibernate开发项目。 下面是一个示例应用程序&#xff1a; 二手技术&#xff1a; JDK 1.6.0_21 Maven的3.0.2 JSF 2.0.3 PrimeFaces 2.2.1 Hibernate3.6.7 MySQL Java连接器5.1.17 MySQL 5.5.8 Apache Tomcat 7.…

帝国 loginjs.php,帝国cms 6.6 后台拿shell

时间:2013-02-27来源:源码库 作者:源码库 文章热度:℃漏洞作者&#xff1a; 付弘雪提交时间&#xff1a; 2013-01-21公开时间&#xff1a; 2013-01-21漏洞类型&#xff1a; 文件上传导致任意代码执行简要描述&#xff1a;帝国cms 6.6版本后台拿shell 比网上流行的方法简单很多由…

带有JSF,Servlet和CDI的DynamicReports和JasperReports

在此示例中&#xff0c;我将展示如何将DynamicReport和JasperReports与Servlet和CDI集成。 工具&#xff1a; TIBCO Jaspersoft Studio-6.0.4。最终版 Eclipse Luna服务版本2&#xff08;4.4.2&#xff09;。 WildFly 8.x应用程序服务器。 这是Eclipse上项目层次结构的屏幕…

swing 聊天气泡背景_Java Swing中的聊天气泡

swing 聊天气泡背景本文将向您解释“如何在Java swing应用程序中绘制聊天气泡&#xff1f;” 聊天气泡与呼出或提示气泡相同。 今天&#xff0c;大多数聊天应用程序都以这种格式显示转换&#xff0c;因此本文将帮助您在用Java swing创建的桌面应用程序中执行相同的操作。 以下课…

jdk7与jdk8环境共存与切换

1&#xff0c;先安装jdk7,配置环境变量JAVA_HOME,然后安装jdk8。 2&#xff0c;安装jdk8后&#xff0c;JAVA_HOME指向未做修改&#xff0c;执行java -version显示还是以前的jdk7版本信息&#xff0c; 3&#xff0c;接下来我们配置环境变量JAVA_HOME,发现配置jdk7的路径,或者配置…

PHP培训选云和数据,送给云和数据郑州分中心PHP培训班全体学员的祝福

在云和数据数百个日日夜夜&#xff0c;郑州PHP培训班的学员们一起成长&#xff0c;从青春懵懂到成熟稳重&#xff0c;从羞涩内敛到侃侃而谈&#xff0c;他们用奋斗和拼搏共同刻画了人生中一段难忘的回忆。12月12日&#xff0c;云和数据郑州分中心PHP培训班毕业典礼&#xff0c;…

cyclicbarrier_Java并发– CyclicBarrier示例

cyclicbarrierJava中的CyclicBarrier是JDK 5中在java.util.Concurrent包上引入的同步器&#xff0c;以及其他并发实用程序&#xff0c;例如Counting Semaphore &#xff0c; BlockingQueue &#xff0c; ConcurrentHashMap等。CyclicBarrier与CountDownLatch类似&#xff0c;我…