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同一了


最後,還是用文件服務器比較好,一勞永逸。




發佈了37 篇原創文章 · 獲贊 16 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章