使用Apache Camel进行负载平衡

在此示例中,我们将向您展示如何使用Apache Camel作为系统的负载平衡器。 在计算机世界中,负载均衡器是一种充当反向代理并在许多服务器之间分配网络或应用程序流量的设备。 负载平衡器用于增加容量(并发用户)和应用程序的可靠性。 借助Camel,我们可以立即制作自己的软件负载平衡器。 享受骑行!

负载均衡不是《企业集成模式》一书中的单独模式(就像克劳斯·易卜生所说的那样,如果本书有第二版的话),但是骆驼把它当作另一个EIP对待。 尽管Camel语法使负载平衡看起来非常容易,但这仍然是一个复杂的话题,您应该花一些时间在设计阶段规划合适的策略。 Camel带有许多内置的负载平衡策略。 在此示例中,我们介绍了其中一些更常用的方法。

本文的代码使用Maven 3.3.9,Eclipse Mars 4.5.0和Apache Camel 2.17.1。 请注意,自2.15版本以来,负载平衡器API有所更改,如果您要使用Camel的早期版本,请查阅文档。 此示例源代码中的所有类都使用@Test带注释的方法,因此您必须将它们作为JUnit测试运行,并希望看到绿色的条。

1.创建基础项目

在继续编写实际代码之前,首先要在Eclipse中创建一个Maven项目。 首先选择File-> New…-> new project。 键入maven并选择Maven项目。

创建一个新的Maven项目

创建一个新的Maven项目

在下一个窗口中,检查创建简单项目选项,然后单击下一步:

创建一个简单的Maven项目

创建一个简单的Maven项目

最后添加以下配置,然后单击完成:

配置Maven项目

配置Maven项目

现在编辑pom.xml文件,如下所示:

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.javacodegeeks</groupId>
<artifactId>camelLoadBalancer</artifactId>
<version>1.0.0-SNAPSHOT</version><dependencies><dependency><groupId>org.apache.camel</groupId><artifactId>camel-core</artifactId><version>2.17.1</version></dependency><dependency><groupId>org.apache.camel</groupId><artifactId>camel-test</artifactId><version>2.17.1</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency></dependencies>
</project>

2.负载均衡

我们提到了骆驼支持的不同政策,但是什么是政策? 策略定义工作负载如何在不同的接收方(处理器,消费者服务…)之间分配。 在本文中,我们播出了随机,轮循及其加权对应项和主题策略的示例。 最后,我们向您展示如何制定自己的政策。

随机

负载平衡策略的最简单形式是随机的。 顾名思义,您只需定义应处理负载的端点,然后Camel即可随机决定使用哪个端点。 这是实现随机策略的代码。 m1,m2和m3是处理消息的端点。 终结点始终会收到该消息,但是每次运行该类时,都会使用上述终结点之一。 这种选择是完全随机的,您可以通过添加自己的断言来检查这种随机性。

RandomLoadBalance.java

package com.jcg;import org.apache.camel.EndpointInject;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.test.junit4.CamelTestSupport;
import org.junit.Test;public class RandomLoadBalance extends CamelTestSupport{@EndpointInject(uri="mock:m1")MockEndpoint m1;@EndpointInject(uri="mock:m2")MockEndpoint m2;@EndpointInject(uri="mock:m3")MockEndpoint m3;@EndpointInject(uri="mock:end")MockEndpoint end;@Overrideprotected RouteBuilder createRouteBuilder() throws Exception{return new RouteBuilder(){@Overridepublic void configure() throws Exception {from("direct:start").loadBalance().random().to(m1,m2,m3).end().to(end);}};}@Testpublic void testSending() throws Exception{end.expectedMessageCount(1);template.sendBody("direct:start", "");end.assertIsSatisfied();}
}

轮巡

轮询是负载平衡的另一种简单类型。 在此策略中,依次依次使用端点。 在示例代码中,您会看到消息通过m1,m2,m3并再次通过m1。

RoundRobinLoadBalance.java

package com.jcg;import javax.naming.Context;
import org.apache.camel.EndpointInject;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.dataset.SimpleDataSet;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.test.junit4.CamelTestSupport;
import org.junit.Test;public class RoundRobinLoadBalance extends CamelTestSupport{@EndpointInject(uri="mock:m1")MockEndpoint m1;@EndpointInject(uri="mock:m2")MockEndpoint m2;@EndpointInject(uri="mock:m3")MockEndpoint m3;@EndpointInject(uri="mock:end")MockEndpoint end;@Overrideprotected RouteBuilder createRouteBuilder() throws Exception{return new RouteBuilder(){@Overridepublic void configure() throws Exception {from("dataset:start").loadBalance().roundRobin().to(m1,m2,m3).end().to(end);}};}@Overrideprotected Context createJndiContext() throws Exception{SimpleDataSet sds = new SimpleDataSet();sds.setSize(4);Context context = super.createJndiContext();context.bind("start", sds);return context;}@Testpublic void testSending() throws Exception{	m1.expectedMessageCount(2);m2.expectedMessageCount(1);m3.expectedMessageCount(1);end.expectedMessageCount(4);template.sendBody("dataset:start", "");m1.assertIsSatisfied();m2.assertIsSatisfied();m3.assertIsSatisfied();end.assertIsSatisfied();}
}

加权轮循

在现实世界中,很少有相同的计算机可以满足您的请求。 因此,拥有一台可能更强大的机器比其他机器做更多的工作有意义。 加权轮询和加权随机分别是轮询策略和随机策略的更复杂对应物。 使用加权轮询(或随机轮询),您可以细粒度地控制负载平衡。 这里我们给出一个加权轮循的例子。 加权随机是相同的。

weight方法有两个参数。 首先是一个布尔值,它定义策略是循环(true)还是随机(false)。 第二个参数是一个字符串,它定义相应端点的分配比率。 这里的“ 2,1”表示m1接收到的流量是m2接收到的流量的两倍。 在早期版本的Camel中,您必须使用整数列表。

WeightedRoundRobinLoadBalance.java

package com.jcg;import javax.naming.Context;
import org.apache.camel.EndpointInject;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.dataset.SimpleDataSet;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.test.junit4.CamelTestSupport;
import org.junit.Test;public class WeightedRoundRobinLoadBalance extends CamelTestSupport{@EndpointInject(uri="mock:m1")MockEndpoint m1;@EndpointInject(uri="mock:m2")MockEndpoint m2;@EndpointInject(uri="mock:end")MockEndpoint end;@Overrideprotected RouteBuilder createRouteBuilder() throws Exception{return new RouteBuilder(){@Overridepublic void configure() throws Exception {// first argument of weighted method is a boolean defines if the policy is// Round robin (true) or Random (false)from("dataset:start").loadBalance().weighted(true,"2,1").to(m1,m2).end().to(end);}};}@Overrideprotected Context createJndiContext() throws Exception{SimpleDataSet sds = new SimpleDataSet();sds.setSize(6);Context context = super.createJndiContext();context.bind("start", sds);return context;}@Testpublic void testSending() throws Exception{m1.expectedMessageCount(4);m2.expectedMessageCount(2);end.expectedMessageCount(6);template.sendBody("dataset:start", "");m1.assertIsSatisfied();m2.assertIsSatisfied();end.assertIsSatisfied();}
}

话题

主题从根本上不同于其他策略,因为所有端点都收到消息。 在我们的示例代码m1,m2和m3中,全部处理5条消息,并且端点也接收5条消息。 主题对于防止端点故障很有用。

TopicLoadBalance.java

package com.jcg;import javax.naming.Context;
import org.apache.camel.EndpointInject;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.dataset.SimpleDataSet;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.test.junit4.CamelTestSupport;
import org.junit.Test;public class TopicLoadBalance extends CamelTestSupport{@EndpointInject(uri="mock:m1")MockEndpoint m1;@EndpointInject(uri="mock:m2")MockEndpoint m2;@EndpointInject(uri="mock:m3")MockEndpoint m3;@EndpointInject(uri="mock:end")MockEndpoint end;@Overrideprotected RouteBuilder createRouteBuilder() throws Exception{return new RouteBuilder(){@Overridepublic void configure() throws Exception {from("dataset:start").loadBalance().topic().to(m1,m2,m3).end().to(end);}};}@Overrideprotected Context createJndiContext() throws Exception{SimpleDataSet sds = new SimpleDataSet();sds.setSize(5);Context context = super.createJndiContext();context.bind("start", sds);return context;}@Testpublic void testSending() throws Exception{	m1.expectedMessageCount(5);m2.expectedMessageCount(5);m3.expectedMessageCount(5);end.expectedMessageCount(5);template.sendBody("dataset:start", "");m1.assertIsSatisfied();m2.assertIsSatisfied();m3.assertIsSatisfied();end.assertIsSatisfied();}
}

自定义负载均衡器

骆驼提供了许多有用的策略,但是总有一些策略无法满足您的需求。 在这种情况下,您必须定义自己的负载平衡策略,但Camel不会让您感到孤独。 自定义负载平衡器使您可以轻松定义自己的策略。 在示例代码中,我们定义了一个负载均衡器,用于检查消息头“ sessionID”字段。 如果是偶数,则将其发送到m1;如果是m2,则将其发送给m1。 当然,这是一个不现实的示例,但是我们故意简化了能够专注于负载平衡实现而又没有业务逻辑混乱的情况。 首先,我们创建一个扩展LoadBalancerSupport类并覆盖处理方法的类。 然后,我们将此类的实例传递给loadBalance方法。

SessionChecker.java

package com.jcg;import org.apache.camel.AsyncCallback;
import org.apache.camel.Exchange;
import org.apache.camel.processor.loadbalancer.LoadBalancerSupport;public class SessionChecker extends LoadBalancerSupport{@Overridepublic boolean process(Exchange exchange, AsyncCallback callback) {int id = exchange.getIn().getHeader("sessionID", Integer.class);try{if(id%2 == 0){getProcessors().get(0).process(exchange);} else{getProcessors().get(1).process(exchange);}}catch(Exception e){e.printStackTrace();}callback.done(true);return true;}
}

CustomLoadBalance.java

package com.jcg;import java.util.HashMap;
import java.util.Map;
import javax.naming.Context;
import org.apache.camel.EndpointInject;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.dataset.SimpleDataSet;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.test.junit4.CamelTestSupport;
import org.junit.Test;public class CustomLoadBalance extends CamelTestSupport{@EndpointInject(uri="mock:m1")MockEndpoint m1;@EndpointInject(uri="mock:m2")MockEndpoint m2;@EndpointInject(uri="mock:end")MockEndpoint end;@Overrideprotected RouteBuilder createRouteBuilder() throws Exception{return new RouteBuilder(){@Overridepublic void configure() throws Exception {from("dataset:start").loadBalance(new SessionChecker()).to(m1,m2).end().to(end);}};}@Overrideprotected Context createJndiContext() throws Exception{SimpleDataSet sds = new SimpleDataSet();Map<String, Object> headers = new HashMap<>();headers.put("sessionID", 1);sds.setDefaultHeaders(headers);sds.setSize(2);Context context = super.createJndiContext();context.bind("start", sds);return context;}@Testpublic void testSending() throws Exception{	m1.expectedMessageCount(0);m2.expectedMessageCount(2);end.expectedMessageCount(2);template.sendBody("dataset:start", "");m1.assertIsSatisfied();m2.assertIsSatisfied();end.assertIsSatisfied();}
}

3.结论

骆驼负载平衡还有更多。 我们没有涵盖诸如故障转移,粘性和断路器之类的策略。 实际上,骆驼不仅仅局限于此。 您可以在更多情况下使用负载平衡,例如客户端和服务器之间的HTTP代理。

4.下载Eclipse项目

这是不同的Camel负载平衡策略的示例。

下载
您可以在此处下载此示例的完整源代码: Camel负载均衡器

翻译自: https://www.javacodegeeks.com/2016/06/load-balancing-apache-camel.html

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

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

相关文章

Java8-Guava实战示例

示例一&#xff1a; 跟示例三对比一下&#xff0c;尽量用示例三 List<InvoiceQueryBean> invoiceQueryBeanList new ArrayList<>(); List<String> invoices Lists.newArrayList(Iterators.transform(invoiceQueryBeanList.iterator(), new Function<Inv…

java项目构建部署包

博客分类&#xff1a; JAVA Java 工程在生产环境运行时&#xff0c;一般需要构建成一个jar&#xff0c;同时在运行时需要把依赖的jar添加到classpath中去&#xff0c;如果直接运行添加classpath很不方便&#xff0c;比较方便的是创建一个shell脚本。在公司项目中看到把工程代码…

不错的自学网站合集

一、网站类1、假期在家如何查找论文资料&#xff1f;只需登录中国图书馆http://t.cn/hYmDq&#xff08;需注册&#xff09;&#xff0c;即可免费下载各种期刊和学位论文2、全球免费开放的电子图书馆http://t.cn/h4hJUf3、给大家推荐个神网站&#xff0c;只要是外文书籍基本上都…

c++中关于字符串的读入——cin、getline、get、gtes(查询+思考+总结)

1、cin读入一个字符&#xff1a;char c;cin>>c;2、cin读入一个字符串&#xff1a;char s[10];cin >> s;&#xff08;c风格字符串&#xff09; string str;cin >> str;&#xff08;c的string&#xff09;3、cin.get()读入一个字符&#xff1a;char c;ccin.…

java文档注释和标题注释_Java注释:探究和解释

java文档注释和标题注释Java 5 SE的许多出色功能之一是Annotations构造的引入。 注释是一些标签&#xff0c;可以将其插入到程序源代码中&#xff0c;以使用某种工具对其进行处理并使其变得有意义。 注释处理工具通常使用&#xff08;Java 5 SE的&#xff09;Reflection API在J…

shell 脚本初步,启动可执行 jar 文件

可能很多同学在看到这篇文章的时候是第一次接触 shell 脚本。所以我们首先需要了解什么是 shell 脚本。在 Windows 里我们经常会看到一种扩展名为 .bat 的文件&#xff0c;它称为批处理文件。批处理文件的作用是把许多个命令放在一个文件里&#xff0c;当运行这个文件的时候就执…

使用Java创建DynamoDB表

在这篇文章中&#xff0c;我们将使用java方法在DynamoDB数据库上创建表。 在开始之前&#xff0c;我们需要安装本地dynamodb&#xff0c;因为我们要避免使用dynamodb的任何费用。 有一个以前的岗位上本地dynamodb。 如果您使用docker&#xff0c;则可以找到本地dynamodb映像&a…

表达式前后缀表达形式 [zz]

(2012-09-12 13:08:39) 转载▼标签&#xff1a; 杂谈 转自&#xff1a;http://blog.csdn.net/whatforever/article/details/673853835,15,,80,70,-,*,20,/ //后缀表达方式(((3515)*(80-70))/20&#xff09;25 //中缀表达方式 /,*,,35,15,-,80,70, 2…

引用:初探Sql Server 执行计划及Sql查询优化

引用:初探Sql Server 执行计划及Sql查询优化 原文:引用:初探Sql Server 执行计划及Sql查询优化初探Sql Server 执行计划及Sql查询优化 收藏MSSQL优化之————探索MSSQL执行计划作者&#xff1a;no_mIss最近总想整理下对MSSQL的一些理解与感悟&#xff0c;却一直没有心思和时间…

Cities

问题 C: Cities 时间限制: 1 Sec 内存限制: 128 MB提交: 87 解决: 61[提交][状态][讨论版][命题人:admin]题目描述 There are n cities in Byteland, and the ith city has a value ai. The cost of building a bidirectional road between two cities is the sum of their v…

spring观察者模式_Spring事件的观察者模式

spring观察者模式介绍 观察者模式的本质是“定义对象之间的一对多依赖关系&#xff0c;以便当一个对象改变状态时&#xff0c;其所有依赖关系都会被通知并自动更新”。 GoF。 观察者模式是发布/订阅模式的子集&#xff0c;它允许许多观察者对象查看事件。 可以在不同的情况下使…

Lombok,自动值和不可变项

我喜欢布兰登&#xff08;Brandon &#xff09;在博客文章中比较Project Lombok &#xff0c; AutoValue和Immutables的建议 &#xff0c;而这篇文章试图做到这一点。 我已经简要概述了Project Lombok &#xff0c; AutoValue和Immutables &#xff0c;但是这篇文章有所不同&am…

linux对于zombie的处理

(Linux基础)[僵尸进程处理] 今天在服务器上推送项目的时候&#xff0c;突然发现很卡。就用top查看了一下&#xff0c;果然此事不简单啊。 top - 10:39:16 up 20 days, 23:11, 2 users, load average: 1.13, 1.09, 1.03 Tasks: 204 total, 2 running, 196 sleeping, 1 sto…

POJ - 1847 Tram(dijkstra)

题意&#xff1a;有向图有N个点&#xff0c;当电车进入交叉口&#xff08;某点&#xff09;时&#xff0c;它只能在开关指向的方向离开。 如果驾驶员想要采取其他方式&#xff0c;他/她必须手动更换开关。当驾驶员从路口A驶向路口B时&#xff0c;他/她尝试选择将他/她不得不手动…

用interrupt()中断Java线程

Javathread 最近在学习Java线程相关的东西&#xff0c;和大家分享一下&#xff0c;有错误之处欢迎大家指正&#xff0e; 假如我们有一个任务如下&#xff0c;交给一个Java线程来执行&#xff0c;如何才能保证调用interrupt()来中断它呢&#xff1f; Java代码 class ATask imple…

activemq和jms_保证主题,JMS规范和ActiveMQ的消息传递

activemq和jms最近&#xff0c;一位客户要求我仔细研究ActiveMQ的“持久”消息的实现&#xff0c;它如何应用于主题以及在存在非持久订户的故障转移方案中会发生什么。 我已经了解到&#xff0c;JMS语义规定&#xff0c;即使面对消息代理提供程序故障&#xff0c;也只能保证主题…

JAVA分代收集机制详解

Java堆中是JVM管理的最大一块内存空间。主要存放对象实例。在JAVA中堆被分为两块区域&#xff1a;新生代&#xff08;young&#xff09;、老年代&#xff08;old&#xff09;。堆大小新生代老年代&#xff1b;&#xff08;新生代占堆空间的1/3、老年代占堆空间2/3&#xff09;新…

FizzBu​​zz Kata与Java流

在柔道练习仅几周之后&#xff0c;我的儿子感到无聊。 他抱怨说自己没有学任何东西&#xff0c;因为他一遍又一遍地做着同样的事情。 混淆学习和做新事物的不仅仅是幼儿。 例如&#xff0c;有多少软件开发人员通过执行kata或参加dojos来进行刻意练习的麻烦&#xff1f; 重复您…

高可用架构

转载于:https://www.cnblogs.com/138026310/p/9088341.html

vc6.0快捷键

2010-09-14 17:46 F1 显示帮助,如果光标停在代码的某个字符上,显示MSDN中相应的帮助内容&#xff08;需要安装MSDN才能使用&#xff09; F2 书签功能: CtrlF2 --在某行设置一个书签(再按一次是取消) F2 --跳到下一个书签位置 ShiftF2 --跳到上一个书签位置 CtrlShiftF2 --删除…