RPC框架之-DUBBO(二)负载均衡

最新的项目用了dubbo框架,原来只有一台provider机器提供服务,但是现在需要扩展到多台provider机,并且由于业务逻辑涉及到了文件加密解密操作,而密钥又是由客户提供的,因此出现了第二次请求过来会由dubbo分发到文件所在位置以外的服务机上,就出现了找不到文件的情况。

ok,作为supportor,开始解决,方案1是直接增加文件服务器来进行,但是由于项目已经上线,改起来麻烦,于是果断pass;

这样就有了方案2,修改dubbo的负载均衡策略,使得每次的业务逻辑在一条流水线上进行。

本文会持续更新,来介绍负载均衡

1. consistenthash--一致性hash算法

使用方式,在服务端注册的时候提供配置

<!-- 声明需要暴露的服务接口 -->
    <dubbo:service interface="DemoService" ref="demoService" loadbalance="consistenthash" />
dubbo对于该算法默认比较的是第一个请求参数,即相同的请求参数会分发到同一台服务机上。

最开始看到这个解释的时候瞬间迷茫了(原谅我的理解力),度娘了一下发现也没有demo,官网也没有提供,好吧,只能让我这种懒人自己来写了。

相关代码已在上面提供下载,这里启动了两台服务机,server 1 和server 2

服务端

	public static void main(String[] args) throws Exception {
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
				new String[] { "classpath:consumer.xml" });
		context.start();

		DemoService demoService = (DemoService) context
				.getBean("demoService");
		while(true){
			String hello = demoService.sayHello("word", "1");
			String hello1 = demoService.sayHello("word", "2");
			System.out.println(hello);
			System.out.println(hello1);
		}
	}

这里我们看到,demoSerivce.sayHello()方法的第一个参数相同。

直接启动,结果如下,可以看到,所有的服务都是由机器2来提供的(也有可能都是1,主要看第一次是由那台服务机提供服务)

server 2 say: Hello word, today is 1
server 2 say: Hello word, today is 2
server 2 say: Hello word, today is 1
server 2 say: Hello word, today is 2
server 2 say: Hello word, today is 1
server 2 say: Hello word, today is 2
server 2 say: Hello word, today is 1
server 2 say: Hello word, today is 2


第二个参数默认上不会对负载结果产生影响(可以通过配置文件来设置对比几个参数,默认是第一个)

因此开始考虑,一致性是通过什么来比对呢?看了一致性算法,果然没看懂,那只能试一试了。。。

开始考虑普通pojo

创建一个Students类,只有两个属性,name和age

		Students s1 = new Students();
		s1.setName("dog");
		s1.setAge(1);
		Students s2 = new Students();
		s2.setName("cat");
		s2.setAge(2);
		DemoService demoService = (DemoService) context.getBean("demoService");
		while (true) {
			String hello = demoService.sayHello(s1);
			String hello1 = demoService.sayHello(s2);
			System.out.println(hello);
			System.out.println(hello1);
		}
运行结果如下,server 1 处理所有的cat,server2处理所有的dog

server 1 say: Hello cat, age is 2
server 2 say: Hello dog, age is 1
server 1 say: Hello cat, age is 2
server 2 say: Hello dog, age is 1
server 1 say: Hello cat, age is 2
server 2 say: Hello dog, age is 1
server 1 say: Hello cat, age is 2
server 2 say: Hello dog, age is 1
修改代码位置,把students对象的创建移动到for循环内

测试结果,说明对比的不是元素属性是否一致,而是和对象地址有关

server 1 say: Hello dog, age is 1
server 2 say: Hello cat, age is 2
server 2 say: Hello dog, age is 1
server 2 say: Hello cat, age is 2
server 2 say: Hello dog, age is 1

修改Students类的序列化参数,发现结果还是与地址有关

因此,最后项目修改如下,

第一次请求-->随机生成一个token-->服务机创建临时文件-->返回文件位置及token

第二次请求,携带token和文件位置-->通过token找到对应服务机-->文件加密-->业务结束

PS,由于比对的是地址值,因此需要设置一个web容器级别的token池,以保证对象一致

不过也有缺点,当消费机也是集群模式的时候,该配置无效。。。因为不同消费机的token地址不一致...

因此,如果是nginx做的前端负载均衡, 需要通过sticky来实现负载均衡(基于cookie),基本上由同一消费机提供服务,这样就能保证token同一了


最后,还是用文件服务器比较好,一劳永逸。




  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值