一、Eureka的高可用性
Eureka下面的服務實例默認每隔30秒會發送一個HTTP心跳給Eureka,來告訴Eureka服務還活着,每個服務實例每隔30秒也會通過HTTP請求向Eureka獲取服務列表,這就相當於一個服務實例一分鍾會與Eureka進行四次請求,當服務實例多了以后,就要考慮Eureka的壓力,如果我們有1000個服務實例,一分鍾就會有4000次請求,平均每秒70次請求,不過Eureka內部是通過內存建立一個HashMap來維護服務實例列表的,並且還做了讀寫分離,所以保證多個實例的心跳是沒有問題的,要注意的是保證Eureka的高可用,生產環境中如果Eureka掛掉,相當於所有實例之間都沒辦法聯系了,我們可以在多台機器上部署Eureka(盡量不要同時在一台機器上部署,因為出問題時,一般整個機器的資源都不能正常使用了),可以部署三個Eureka實例,然后將每個服務實例同時注冊到三台Eureka上面,這樣即使某個Eureka掛掉了,也不會影響整個系統的運行。
配置的方式也很簡單,部署好多台Eureka實例后,只需要將每個服務實例分別注冊到每個Eureka上面即可
eureka: client: serviceUrl: defaultZone: http://eureka1:80/eureka/, http://eureka2:80/eureka/
二、服務熔斷和服務降級
微服務之間的調用兩種情況,網關與服務之間的調用,服務與服務之間的調用,當某個服務的響應時間過長,調用鏈就會等待,當請求量多了,就會引起雪崩,所以就需要用到服務熔斷組件hystrix,當調用超時時直接返回,並且設置服務降級策略,當發生熔斷時的補救措施,比如監控告警,記錄SQL日志后續進行數據恢復等
1、服務降級配置
當出現服務熔斷時,我們需要配置服務熔斷的處理策略,服務降級有兩種情況,網關層面做降級和服務之間做降級
(1)網關層面降級:只需要重寫ZuulFallbackProvider的方法,即可定制返回值
@Component public class GatewayFallback implements ZuulFallbackProvider { @Override public String getRoute() { // 這里配置服務降級是針對哪個服務實例的,可以填寫服務id,如果返回null則是針對所有服務 return null; } @Override public ClientHttpResponse fallbackResponse() { // 服務熔斷后,返回的內容 return new ClientHttpResponse() { @Override public InputStream getBody() throws IOException { JSONObject result = new JSONObject(); result.put("error_code", -1); result.put("error_info", "網絡繁忙"); return new ByteArrayInputStream(result.toString().getBytes("UTF-8")); } @Override public HttpHeaders getHeaders() { // 返回Json格式的數據 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON_UTF8); return headers; } @Override public HttpStatus getStatusCode() throws IOException { // 返回的HTTP錯誤碼 return HttpStatus.OK; } @Override public int getRawStatusCode() throws IOException { return HttpStatus.OK.value(); } @Override public String getStatusText() throws IOException { return HttpStatus.OK.getReasonPhrase(); } @Override public void close() { // 進行一些自定義的處理,比如監控告警 } }; } }
(2)服務之間降級:服務之間的調用一般是使用Feign組件,我們需要為Feign接口聲明的每個方法編寫處理的邏輯,通過注解的fallback屬性來指定服務降級的實現類
@FeignClient(value = "clientService", fallback = ClientServiceFallback.class) public interface ClientService { @RequestMapping(method = RequestMethod.POST, value = "/test", produces = MediaType.APPLICATION_JSON_VALUE) String queryClientById(@RequestParam("id") String id); }
public class ClientServiceFallback implements ClientService { @Override public String queryClientById(String id) { // 進行一些自定義的處理 return null; } }
2、服務熔斷配置
服務熔斷的參數配置非常重要,合理的參數配置才能更好地利用好機器資源,既不會浪費,也能合理對服務進行熔斷防止雪崩
(1)熔斷超時時間設置:這個時間一定要根據情況合理選擇,不能太高也不能太低,如果設置太高,當服務出現問題時,每個線程都要等待很久,所有線程卡死就會導致用戶根本無法正常使用,如果太小,出現網絡波動就會影響服務質量,合理的設置一般是比如你的接口處理時間是200ms,那你可以設置300ms,比正常的響應時間大一點點,防止網絡波動出現熔斷
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 300
(2)Hystrix線程池大小設置:首先評估你的服務壓力,比如你的服務每秒需要處理100個請求,每個請求的處理時間是200ms,相當於1個線程1秒可以處理5個請求,100/5=20,可以算出20個線程就可以處理請求,我們設置就可以設置25個線程,多給5個線程用來留些后路,防止一些特點時間點有大量的請求
hystrix.threadpool.default.coreSize: 25
三、最后
應對高並發,最重要還是先要保證業務邏輯的處理速度,才能從根本上優化,比如進行SQL查詢時,盡量避免多表關聯,SQL語句越簡單越好,數據表加索引,不要使用外鍵,外鍵會在一定程度上影響性能,且不容易維護,我個人建議通過增加其他表的id字段來維護表之間的關系