(轉)Spring Cloud(二)
阿新 • • 發佈:2018-12-10
(二期)23、微服務框架spring cloud(二)
解決方向
- 為網路其請求設定超時時間
- 使用斷路器模式
- 包裹請求
- 跳閘機制
- 資源隔離
- 監控
- 回退機制
- 自我修復
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
@EnableHystrix
或者
@EnableCircuitBreaker
@HystrixCommand(fallbackMethod = "getUsernameFallback")
@GetMapping("/username")
public Object getUsername() {
return restTemplate.getForObject("http://EUREKA-CLIENT-2/username", String.class);
}
public Object getUsernameFallback() {
return "fall back";
}
預設提示:@HystrixCommand可以和@DefaultProperties配合使用
@hystrixCommand註解引數詳解
/**
* Feign的fallback測試類
* 使用@FeignClient的fallback屬性指定回退類
*/
@FeignClient(name = "microservice-provider-user", fallback = FeignClientFallback.class)
public interface UserFeignClient {
@GetMapping(value = "/{id}")
User findById(@PathVariable("id") Long id);
}
/**
* 回退類FeignClientFallback需實現Feign Client介面
* FeignClientFallback也可以是public class,沒有區別
*/
@Component
class FeignClientFallback implements UserFeignClient {
@Override
public User findById(Long id) {
User user = new User();
user.setId(-1L);
user.setUsername("預設使用者");
return user;
}
}
feign:
hystrix:
enabled: true
@FeignClient(name = "eureka-client-2", fallbackFactory = Demo2ClientFallbackFactory.class)
public interface Demo2Client {
@GetMapping("/username")
public String getUsername();
}
@Component
public class Demo2ClientFallbackFactory implements FallbackFactory<Demo2Client> {
public Demo2Client create(Throwable cause) {
return new Demo2Client() {
@Override
public String getUsername() {
System.out.println(cause.toString());
return "hello world fallbackfactory";
}
};
}
}
在實際開發中,並不是所有的請求都要提前預備好服務降級問題,如果我就是要將服務呼叫失敗的資訊展示給使用者,那麼此時就沒有必要新增斷路器了。
Hystrix斷路器模式的狀態監控
<!--actuator用於應用監控管理-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
management:
endpoint:
health:
show-details: always
#說明斷路器已經開啟
Hystrix circuit short-circuited and is OPEN
https://www.cnblogs.com/java-synchronized/p/7927726.html
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
# 路由規則配置
zuul:
routes:
api-a:
path: /usernameByFeign
serviceId: eureka-client-1
- PRE:
- ROUTING:
- POST:
ERROR:
public class PreLogFilter extends ZuulFilter {
/**
* pre請求之前
* route用於將請求路由轉到微服務
* post路由到微服務以後執行
* error在其他階段發生錯誤的時候執行
* @return
*/
@Override
public String filterType() {
return "pre";
}
/**
* 執行順序
* @return
*/
@Override
public int filterOrder() {
return 0;
}
/**
* true返回一個boolean判斷該過濾器是否要執行
* @return
*/
@Override
public boolean shouldFilter() {
return true;
}
/**
* 過濾器執行具體內容
* @return
* @throws ZuulException
*/
@Override
public Object run() throws ZuulException {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
System.out.println("---》路由獲取所有引數值" + request.getParameterMap().toString());
System.out.println(request.getHeader("cookie"));
return null;
}
}
@Bean
PreLogFilter preLogFilter() {
return new PreLogFilter();
}
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>27.0-jre</version>
</dependency>
import com.google.common.util.concurrent.RateLimiter;
import com.netflix.zuul.ZuulFilter;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
/**
* 限流
*/
public class RateLimiterFilter extends ZuulFilter {
//guava的令牌桶演算法
private static final RateLimiter RATE_LIMITER = RateLimiter.create(100);
@Override
public String filterType() {
return PRE_TYPE;
}
@Override
public int filterOrder() {
return -5;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run(){
if(!RATE_LIMITER.tryAcquire()) {
throw new RuntimeException("佔坑失敗~~");
}
System.out.println("-------->沒限流");
return null;
}
}
@Bean
RateLimiterFilter rateLimiterFilter() {
return new RateLimiterFilter();
}