SpringCloud应对高并发的思路
一、Eureka的高可用性
Eureka下面的服務(wù)實例默認(rèn)每隔30秒會發(fā)送一個HTTP心跳給Eureka,來告訴Eureka服務(wù)還活著,每個服務(wù)實例每隔30秒也會通過HTTP請求向Eureka獲取服務(wù)列表,這就相當(dāng)于一個服務(wù)實例一分鐘會與Eureka進(jìn)行四次請求,當(dāng)服務(wù)實例多了以后,就要考慮Eureka的壓力,如果我們有1000個服務(wù)實例,一分鐘就會有4000次請求,平均每秒70次請求,不過Eureka內(nèi)部是通過內(nèi)存建立一個HashMap來維護(hù)服務(wù)實例列表的,并且還做了讀寫分離,所以保證多個實例的心跳是沒有問題的,要注意的是保證Eureka的高可用,生產(chǎn)環(huán)境中如果Eureka掛掉,相當(dāng)于所有實例之間都沒辦法聯(lián)系了,我們可以在多臺機(jī)器上部署Eureka(盡量不要同時在一臺機(jī)器上部署,因為出問題時,一般整個機(jī)器的資源都不能正常使用了),可以部署三個Eureka實例,然后將每個服務(wù)實例同時注冊到三臺Eureka上面,這樣即使某個Eureka掛掉了,也不會影響整個系統(tǒng)的運行。
配置的方式也很簡單,部署好多臺Eureka實例后,只需要將每個服務(wù)實例分別注冊到每個Eureka上面即可
eureka:
client:
serviceUrl:
defaultZone: http://eureka1:80/eureka/, http://eureka2:80/eureka/
二、服務(wù)熔斷和服務(wù)降級
微服務(wù)之間的調(diào)用兩種情況,網(wǎng)關(guān)與服務(wù)之間的調(diào)用,服務(wù)與服務(wù)之間的調(diào)用,當(dāng)某個服務(wù)的響應(yīng)時間過長,調(diào)用鏈就會等待,當(dāng)請求量多了,就會引起雪崩,所以就需要用到服務(wù)熔斷組件hystrix,當(dāng)調(diào)用超時時直接返回,并且設(shè)置服務(wù)降級策略,當(dāng)發(fā)生熔斷時的補(bǔ)救措施,比如監(jiān)控告警,記錄SQL日志后續(xù)進(jìn)行數(shù)據(jù)恢復(fù)等
1、服務(wù)降級配置
當(dāng)出現(xiàn)服務(wù)熔斷時,我們需要配置服務(wù)熔斷的處理策略,服務(wù)降級有兩種情況,網(wǎng)關(guān)層面做降級和服務(wù)之間做降級
(1)網(wǎng)關(guān)層面降級:只需要重寫ZuulFallbackProvider的方法,即可定制返回值
@Component
public class GatewayFallback implements ZuulFallbackProvider
{
@Override
public String getRoute()
{
// 這里配置服務(wù)降級是針對哪個服務(wù)實例的,可以填寫服務(wù)id,如果返回null則是針對所有服務(wù)
return null;
}
@Override
public ClientHttpResponse fallbackResponse()
{
// 服務(wù)熔斷后,返回的內(nèi)容
return new ClientHttpResponse()
{
@Override
public InputStream getBody() throws IOException
{
JSONObject result = new JSONObject();
result.put("error_code", -1);
result.put("error_info", "網(wǎng)絡(luò)繁忙");
return new ByteArrayInputStream(result.toString().getBytes("UTF-8"));
}
@Override
public HttpHeaders getHeaders()
{
// 返回Json格式的數(shù)據(jù)
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()
{
// 進(jìn)行一些自定義的處理,比如監(jiān)控告警
}
};
}
}
(2)服務(wù)之間降級:服務(wù)之間的調(diào)用一般是使用Feign組件,我們需要為Feign接口聲明的每個方法編寫處理的邏輯,通過注解的fallback屬性來指定服務(wù)降級的實現(xiàn)類
@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)
{
// 進(jìn)行一些自定義的處理
return null;
}
}
2、服務(wù)熔斷配置
服務(wù)熔斷的參數(shù)配置非常重要,合理的參數(shù)配置才能更好地利用好機(jī)器資源,既不會浪費,也能合理對服務(wù)進(jìn)行熔斷防止雪崩
(1)熔斷超時時間設(shè)置:這個時間一定要根據(jù)情況合理選擇,不能太高也不能太低,如果設(shè)置太高,當(dāng)服務(wù)出現(xiàn)問題時,每個線程都要等待很久,所有線程卡死就會導(dǎo)致用戶根本無法正常使用,如果太小,出現(xiàn)網(wǎng)絡(luò)波動就會影響服務(wù)質(zhì)量,合理的設(shè)置一般是比如你的接口處理時間是200ms,那你可以設(shè)置300ms,比正常的響應(yīng)時間大一點點,防止網(wǎng)絡(luò)波動出現(xiàn)熔斷
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 300
(2)Hystrix線程池大小設(shè)置:首先評估你的服務(wù)壓力,比如你的服務(wù)每秒需要處理100個請求,每個請求的處理時間是200ms,相當(dāng)于1個線程1秒可以處理5個請求,100/5=20,可以算出20個線程就可以處理請求,我們設(shè)置就可以設(shè)置25個線程,多給5個線程用來留些后路,防止一些特點時間點有大量的請求
hystrix.threadpool.default.coreSize: 25
三、最后
應(yīng)對高并發(fā),最重要還是先要保證業(yè)務(wù)邏輯的處理速度,才能從根本上優(yōu)化,比如進(jìn)行SQL查詢時,盡量避免多表關(guān)聯(lián),SQL語句越簡單越好,數(shù)據(jù)表加索引,不要使用外鍵,外鍵會在一定程度上影響性能,且不容易維護(hù),我個人建議通過增加其他表的id字段來維護(hù)表之間的關(guān)系
總結(jié)
以上是生活随笔為你收集整理的SpringCloud应对高并发的思路的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 无人再提华强北
- 下一篇: 中文分词工具简介与安装教程(jieba、