Java架構學習(四十一)SpringCloud&基礎回顧&使用Fegin客戶端呼叫&服務雪崩效應產生原因&Jmeter模擬服務雪崩效應&解決雪崩效應辦法&Hystrix解決雪崩效應&相關面試
阿新 • • 發佈:2018-12-21
前置知識
SpringCloud 是微服務解決框架,主要應用在RPC遠端呼叫。
2、裡面集成了Eureka註冊中心、Ribbon負載均衡客戶端、Zuul介面閘道器
分散式配置中心。
3、SpringCloud客戶端呼叫工具、rest、fegin。
4、SpringCloud斷路器Hystrix服務降級、熔斷機制、限流。
其實總結高併發就一句話:通過負載均衡達和反向代理達到分流、通過限流達到防服務雪崩、通過服務降級達到部分故障服務依舊可用、通過隔離達到當某些服務故障不影響到其他服務、通過設定超時時間與重試機制達到防止請求堆積
一、使用Fegin客戶端呼叫工具
pom.xml匯入
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.leeue</groupId> <artifactId>41_service-order-fegin</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.2.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.RC1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> </project>
MemberFegin.java fegin呼叫service
package com.leeue.service; import java.util.List; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.web.bind.annotation.RequestMapping; /** * @classDesc: 功能描述:(使用fegin來呼叫介面) * @author:<a href="[email protected]">李月</a> * @Version:v1.0 * @createTime:2018年11月11日 下午7:28:19 */ @FeignClient(value="service-member") // 這上面value值寫你要呼叫的服務名稱 public interface MemberFegin { @RequestMapping("/getMemberAll") // 這上面寫你要呼叫的服務的介面地址 也就是service-member服務立馬的Mapping public List<String> getToOrderMemberAll(); //Fegin底層也是會發出HttpClient請求來進行呼叫service-member服務地址 }
OrderFeginController.java 控制層
package com.leeue.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.leeue.service.MemberFegin; @RestController public class OrderFeginController { @Autowired private MemberFegin memberFegin; @RequestMapping("/getToOrderMemberAll") public List<String> getToOrderMemberAll(){ System.out.println("order fegin 工程呼叫 member工程"); return memberFegin.getToOrderMemberAll(); } }
application.yml檔案
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8888/eureka/
server:
port: 8765
spring:
application:
name: service-order-fegin
OrderFegin.java
package com.leeue;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients // 使用Fegin來呼叫服務 要在啟動類上加上這個註解
public class OrderFegin {
public static void main(String[] args) {
SpringApplication.run(OrderFegin.class, args);
}
}
呼叫連結:http://localhost:8765/getToOrderMemberAll
要注意的是fegin裡面是自帶負載均衡的。路由策略是輪訓機制
二、服務雪崩效應產生原因
什麼是服務雪崩效應?
答:雪崩效應,所有的請求在處理一個服務,這個時候
就會產生服務堆積,就不能進行訪問改服務的其他介面了。
解決方案:
1、使用超時機制、服務降級()
服務降級:就是在服務呼叫介面的時候如果發生錯誤或者超時的情況下,
就不讓其呼叫介面,呼叫本地的fallback,返回服務錯誤,或者服務請求過多這種提示。
三、模擬服務雪崩效應操作使用Jmeter來模擬
四、解決雪崩效應的方法
服務雪崩產生原因:是因為服務產生了堆積,導致了該服務的其他介面無法被呼叫。
如何解決服務雪崩效應?
1、設定超時機制 --- 如果訂單服務呼叫會員服務介面沒有在 規定的時間響應回
來就返回給客戶端說連線超時等訊息
2、使用服務降級:服務介面發生錯誤的時候,不去呼叫介面,呼叫本地方法。
在SpringCloud 中是 fallback。本地方法。給客戶端一個反饋結果:
當前訪問人數過多請稍後重試等訊息。
3、熔斷機制:類似保險絲。--- 一旦達到了規定請求數量、就熔斷報錯
-- 服務降級類似
4、使用服務的隔離機制 --- 每個服務介面都把隔離開來。
A介面
自己有獨立的執行緒池、
B介面
執行緒池 在A介面有大量訪問的時候不影響B介面的訪問。
5、服務的限流機制。
使用閘道器zuul 或 nginx來做 介面達到一定次數的時候 就返回錯誤。
五、使用SpringCloud中Hystrix實現服務的降級
Hystrix 斷路器:當我們使用rpc遠端呼叫的時候,解決服務雪崩效應。
hystrix是專門解決服務與服務之間的報錯資訊。
hystrix:斷路器,裡面有服務降級、熔斷機制、服務隔離。
在使用hystrix專案中pom.xml檔案加入
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
application.yml檔案
# 開啟hystrix 斷路器
feign:
hystrix:
enabled: true
啟動OrderFegin這個服務
再次訪問的時候就就沒有轉圈,而是直接丟擲服務異常這種。
在SpringCloud中預設服務之間呼叫服務要在1秒內返回結果。
這裡是要3秒才能返回結果,所以hystrix進行了服務的降級
這裡使用了服務降級。
在application.yml設定超時時間。
###超時時間
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 4000
超時時間在5-10秒之間
解決程式碼:
package com.leeue.fallback;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Component;
import com.leeue.service.MemberFegin;
/**
* @classDesc: 功能描述:(使用hystrix 斷路器做的服務降級)
* @author:<a href="[email protected]">李月</a>
* @Version:v1.0
* @createTime:2018年11月14日 上午11:50:51
*/
@Component //注入到Spring容器裡面去
public class MemberFallBack implements MemberFegin{
/**
* 對 getToOrderMemberAll這個介面進行服務降級處理
*/
// 這個是講課的例子 在公司裡面 不是返回型別是 String的
@Override
public List<String> getToOrderMemberAll() {
//做服務的降級處理
List<String> list = new ArrayList<String>();
list.add("服務發生異常....當前不能訪問");
return list;
}
}
package com.leeue.service;
import java.util.List;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import com.leeue.fallback.MemberFallBack;
/**
* @classDesc: 功能描述:(使用fegin來呼叫介面)
* @author:<a href="[email protected]">李月</a>
* @Version:v1.0
* @createTime:2018年11月11日 下午7:28:19
*/
@FeignClient(value="service-member",fallback=MemberFallBack.class) // 這上面value值寫你要呼叫的服務名稱
public interface MemberFegin {
@RequestMapping("/getMemberAll") // 這上面寫你要呼叫的服務的介面地址 也就是service-member服務立馬的Mapping
public List<String> getToOrderMemberAll();
//Fegin底層也是會發出HttpClient請求來進行呼叫service-member服務地址
}
六、使用hystrix解決服務雪崩效應
上面是fegin 呼叫解決雪崩效應,使用的是服務降級
七、SpringCloud相關面試
1、微服務情況下,怎麼解決服務雪崩效應。
答:使用hystrix、服務降級、服務隔離、使用閘道器限流
2、SpringCloud與SpringBoot區別
答:SpringBoot解決的問題是,能快速整合第三方框架,
簡化xml配置,自帶容器,預設整合web元件springMVC
SpringCloud微服務解決框架依賴與SpringBoot.
使用SpringMVC作為RPC呼叫框架書寫介面。
有A服務 B服務 怎麼讓B 服務只能讓A服務訪問 解決方案: 在微服務裡面使用介面閘道器 來判斷介面請求來源是那個服務 底層原理是判斷http請求來源