摘要:沒有顯式的通常調用需要指定域名才能定位到某個服務器上的某個具體應用,而通過的注冊中心,在調用時只需指定服務名稱,注冊中心會自動發現對應的具體服務。
起因
公司要做系統間的互通,所以需要程序之間互相調用接口,這塊一直是其他同事在做,但是今天一個新項目需要調用到其他系統的接口,所以看了下他們的調用方法,發現都是傳統的httpclient調用,外面做了一層封裝,類似這樣:
HttpGet httpGet = new HttpGet(url); HttpClient client = new DefaultHttpClient(); HttpResponse resp = client.execute(httpGet); HttpEntity entity = resp.getEntity(); String respContent = EntityUtils.toString(entity, "utf-8").trim(); httpGet.abort(); client.getConnectionManager().shutdown(); return respContent;
然后在調用的時候,大概是這樣:
String urls = mapToUrl("");//這里是組合URL的方法 String result = HttpClients.clientDoPost(urls);//這里就是調用上面封裝的httpclient JSONObject json = JSONObject.parseObject(result);//解析返回值
這樣有什么弊端呢?在我看來最大的一點就是,調用方法沒有語義化。
稍微解釋一下,這種方法調用寫在controller里面,給其他人員看到,首先會理解為:
先組合一下URL和參數
然后發起一個http請求
最后解析http的response
貌似看起來很清晰,其實不然,對整個項目不熟悉的人,完全不知道這三行代碼做了哪些事情,做了具體哪些業務操作,只知道我調用了一次http請求。
所以,我決定對項目整體的結構進行改造,然后才有了今天這篇文章。
公司有很多項目,之前都是外包出去做的,各種語言各種框架的都有,自我入職以來,新的項目我都采用了springboot框架,同時,也讓同事使用了這個框架。
所以這次改造,我打算接入springcloud,它和springboot無縫銜接這種天然的優勢必須要好好利用。但是還有一些其他項目沒有用到springboot,考慮到這種接入cloud比較困難,所以繼續保留了httpclient的調用方式。然后設計出大致的結構:
既然打算要接入,總要說下好處,不然不能讓別人信服,我大致列出來四個。
接入簡單
在springboot上接入springcloud并注冊eureka服務器,只需要簡單幾步,加幾個注解就可以完成。
沒有顯式的IP
通常httpclient調用需要指定 IP+context||域名+context 才能定位到某個服務器上的某個具體應用,而通過springcloud的eureka注冊中心,在調用時只需指定服務名稱,注冊中心會自動發現對應的具體服務。
自動負載均衡
普通的http后臺要做負載均衡,需要借助Nginx或者Apache這樣的第三方proxy程序,而springcloud的fegin客戶端會自動完成負載操作,發現eureka注冊中心上所有可用的服務。
強語義化
fegin客戶端調用http方法只需要和被調用的方法有一樣的方法聲明,requestParam注解,只需定義一下接口,feginClient注解會自動幫你實現,這樣就可以像調用本地方法一樣調用遠程接口了。具體設計
之前確定了整體的結構,現在就要把實現具體化,首先要把springcloud的服務和普通的http服務聯系在一起,然后再具體到某個服務的調用。這里畫了一個大致的圖例。
普通的http服務還使用httpclient調用,只是多封裝了一層語義化,這里先不贅述了,下面說下springcloud服務化以及調用eureka和普通http接口的方法。
注冊中心首先要啟動注冊中心,去springcloud的GitHub下載Eureka Sample注冊中心模板,然后修改配置,放到服務器上運行。
注冊eureka服務首先,要使一個springboot程序注冊為eureka服務,要引入maven包(沒有使用maven管理項目的童鞋要自己導包了)
org.springframework.cloud spring-cloud-starter-eureka org.springframework.cloud spring-cloud-starter-feign
加入dependentsManage管理版本
org.springframework.cloud spring-cloud-dependencies Dalston.SR4 pom import
然后在controller上加上注解@EnableEurekaClient注解
@EnableEurekaClient @RestController public class TestController { }
然后在springbootApplication啟動類上要加上@EnableDiscoveryClient,@EnableFeignClients,使它擁有一個fegin客戶端的能力。這里就不貼代碼了。
最后要修改springboot的配置文件application.yml,增加eureka服務器和自身應用名稱的配置
eureka: client: serviceUrl: defaultZone: http://ip:port/eureka/ spring: application: name: your-application-Name
這樣,你的原有的服務就被改造成springcloud微服務了。
fegin調用fegin調用很簡單,只要在接口上加上@FeignClient(value = "應用名"),然后定義下調用的接口聲明,就可以了
//原接口 @RequestMapping(value = "/hi",method = RequestMethod.GET) public String sayHiFromClientOne(@RequestParam(value = "name") String name){ return "hello "+name; } //fegin客戶端 @FeignClient(value = "sportsHealth") public interface TestfeginClient { @RequestMapping(value = "/hi",method = RequestMethod.GET) String sayHiFromClientOne(@RequestParam(value = "name") String name); }Http調用
這里在httpclient基礎上封裝成語義化的調用。
//繼承fegin接口的方法 public interface TestHttpClient extends TestfeginClient { } //實現類 @Service public class TestHttpClientImpl implements TestHttpClient { @Override public ConcretObject sayHiFromClientOne(String name) { Mapmap = new HashMap<>(); map.put("name",name); String urls=MapToUrl("ip"+"context", map); String result = HttpClients.clientDoPost(urls); ConcretObject ret= JSONObject.parseObject(result, ConcretObject .class); return ret; }
這樣調用起來就和fegin以及本地方法無二了
//先注入 @Autowired private TestFeginClient testFeginClient; @Autowired private TestHttpClient testHttpClient; //調用Fegin testFeginClient.sayHiFromClientOne("張三"); //調用Http testHttpClient.sayHiFromClientOne("李四");Facade Service
雖然現在以及很簡單了,但是現在存在一些普通的http接口,以及有些http接口后面要注冊到eureka服務但是現在還沒接入的。為了盡量統一化調用,不在業務層里httpclient,feginclient混亂調用,我們建立一層facade層,統一化調用,先調用fegin客戶端,失敗后嘗試http調用(ps:這會產生一些性能開銷,對實時性要求很強的公司最好就別這樣做了,這里是因為我們的實時性并不強,可以接受一點延遲,結合實際情況使用的)
下面是簡單的sample:
//先繼承feginclient接口 public interface TestFacade extends TestFeginClient { } //實現facade @Service public class TestFacadeImpl implements TestFacade { //先注入 @Autowired private TestFeginClient testFeginClient; @Autowired private TestHttpClient testHttpClient; //實現接口方法 @Override public ConcretObject sayHiFromClientOne(String name) { ConcretObject obj; try { //調用feginclient obj= testFeginClient.sayHiFromClientOne(name); }catch (Exception e){ try { //調用httpclient obj= testHttpClient.sayHiFromClientOne(name); }catch (Exception e1){ //都調用失敗處理 obj= new ConcretObject (); obj.setCode("1"); obj.setMessage("調用失敗"); } } return obj; } }結束
以上就是我的初衷到設計思路到具體的實現,springcloud還有很多強大的成員:斷路器,路由,。。。目前還沒有用上,當然,我也在學習過程中,希望能和大家一起交流,最后附上我的GitHub,歡迎給我star。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/67898.html
摘要:而在這個微服務下,同樣需要進行數據操作,我不可能還要在下再一次進行集成,這樣大大的增加了代碼量。其次,是將有關數據操作的都單獨部署成一個模塊,比如我集成的模塊,集成的模塊,使用作為內存緩存模塊。 前言 相對于 spring 對 mybatis 以及 redis 等的整合所需要的各種配置文件,在 springboot 下,已經大大的簡化了,你可能只是需要增加個依賴,加個注解,然后在配置文...
摘要:集群系統中的單個計算機通常稱為節點,通常通過局域網連接,但也有其它的可能連接方式。這樣就高興了,可以專心寫自己的,前端就專門交由小周負責了。于是,小周和就變成了協作開發。都是為了項目正常運行以及迭代。 一、前言 只有光頭才能變強 認識我的朋友可能都知道我這陣子去實習啦,去的公司說是用SpringCloud(但我覺得使用的力度并不大啊~~)... 所以,這篇主要來講講SpringClou...
閱讀 2597·2021-10-14 09:43
閱讀 3559·2021-10-13 09:39
閱讀 3289·2019-08-30 15:44
閱讀 3137·2019-08-29 16:37
閱讀 3702·2019-08-29 13:17
閱讀 2731·2019-08-26 13:57
閱讀 1825·2019-08-26 11:59
閱讀 1238·2019-08-26 11:46