①服務降級。
什麼是服務降級:
整體資源快不夠了,忍痛將某些服務先關掉,待渡過難關,再開啓回來。
服務降級處理是在客戶端(服務消費者、服務調用方)實現完成的,與服務端(服務提供者)沒有關係。
服務熔斷的壞處:容易方法膨脹。增加一個方法,就要增加一個fallbackMethod方法。而且出現高耦合現象。這時,我們需要解耦:
microservicecloud-provider-dept-hystrix-8001子工程的DeptController.java的全部內容是:
package com.lss.springcloud.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.lss.springcloud.entities.Dept;
import com.lss.springcloud.service.DeptService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
@RestController
public class DeptController {
@Autowired
private DeptService service;
@Autowired
private DiscoveryClient client;
@RequestMapping(value = "/dept/add", method = RequestMethod.POST)
public boolean add(@RequestBody Dept dept) {
return service.add(dept);
}
@RequestMapping(value = "/dept/get/{id}", method = RequestMethod.GET)
//@HystrixCommand(fallbackMethod = "processHystrix_Get")解耦
public Dept get(@PathVariable("id") Long id) {
Dept dept = this.service.get(id);
if (null == dept) {
throw new RuntimeException("該ID:" + id + "沒有沒有對應的信息");
}
return dept;
}
// public Dept processHystrix_Get(@PathVariable("id") Long id) {
// return new Dept().setDeptno(id).setDname("該ID:" + id + "沒有沒有對應的信息,null--@HystrixCommand")
// .setDb_source("no this database in MySQL");
// }
@RequestMapping(value = "/dept/list", method = RequestMethod.GET)
public List<Dept> list() {
return service.list();
}
@RequestMapping(value = "/dept/discovery", method = RequestMethod.GET)
public Object discovery() {
// 盤點eureka裏面的微服務有哪些。
List<String> list = client.getServices();
System.out.println("**********" + list);
List<ServiceInstance> srvList = client.getInstances("MICROSERVICECLOUD-DEPT");
for (ServiceInstance element : srvList) {
System.out.println(element.getServiceId() + "\t" + element.getHost() + "\t" + element.getPort() + "\t"
+ element.getUri());
}
return this.client;
}
}
第一步:修改microservicecloud-api工程,根據已經有的DeptClientService接口新建一個實現了,FallbackFactory接口的類DeptClientServiceFallbackFactory。
DeptClientServiceFallbackFactory.java的內容是:
千萬不要忘記在類上面新增@Component註解!!!
package com.lss.springcloud.service;
import java.util.List;
import org.springframework.stereotype.Component;
import com.lss.springcloud.entities.Dept;
import feign.hystrix.FallbackFactory;
@Component//不要忘記添加,不要忘記添加
public class DeptClientServiceFallbackFactory
implements FallbackFactory<DeptClientService>{
@Override
public DeptClientService create(Throwable arg0) {
return new DeptClientService() {
@Override
public List<Dept> list() {
return null;
}
@Override
public Dept get(long id) {
return new Dept().setDeptno(id)
.setDname("該ID:"+id+"沒有沒有對應的信息,Consumer客戶端提供的降級信息,此刻服務Provider已經關閉")
.setDb_source("no this database in MySQL");
}
@Override
public boolean add(Dept dept) {
return false;
}
};
}
}
第二步:修改microservicecloud-api工程,DeptClientService接口在註解@FeignClient中添加fallbackFactory屬性值。
microservicecloud-api子模塊工程的DeptClientService.java接口的完整內容是:
package com.lss.springcloud.service;
import java.util.List;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.lss.springcloud.entities.Dept;
//@FeignClient(value = "MICROSERVICECLOUD-DEPT")
@FeignClient(value = "MICROSERVICECLOUD-DEPT",
fallbackFactory=DeptClientServiceFallbackFactory.class)
public interface DeptClientService {
@RequestMapping(value = "/dept/get/{id}", method = RequestMethod.GET)
public Dept get(@PathVariable("id") long id);
@RequestMapping(value = "/dept/list", method = RequestMethod.GET)
public List<Dept> list();
@RequestMapping(value = "/dept/add", method = RequestMethod.POST)
public boolean add(Dept dept);
}
接口裏面的所有方法出現問題,如get、list或者add出現問題,則找FeignClient裏面的fallbackFactory裏面的DeptClientServiceFallbackFactory.class這個位元碼對應的類DeptClientServiceFallbackFactory..java。裏面定義了當方法get、list或者add出現問題後的處理方法。
第三步:microservicecloud-api工程進行maven clean和maven install。
第四步:microservicecloud-consumer-dept-feign工程修改YML。
yml需要增加的內容是:
feign:
hystrix:
enabled: true
yml修改後的完整內容是:
server:
port: 83
spring:
application:
name: microservicecloud-dept-consumer
feign:
hystrix:
enabled: true
eureka:
client:
register-with-eureka: true
service-url:
defaultZone: http://192.168.10.109:7001/eureka/,http://192.168.10.110:7002/eureka/,http://192.168.10.111:7003/eureka/
instance:
instance-id: microservicecloud-consumer-dept80 #自定義服務名稱信息
prefer-ip-address: true #訪問路徑可以顯示IP地址
測試:3個eureka先啓動,再微服務microservicecloud-provider-dept-8001啓動,再啓動microservicecloud-consumer-dept-feign。
http://192.168.10.115:83/consumer/dept/get/1
故意關閉微服務microservicecloud-provider-dept-8001
http://192.168.10.115:83/consumer/dept/get/1
此時服務端provider已經down了,但是我們做了服務降級處理,讓客戶端在服務端不可用時也會獲得提示信息而不會掛起耗死服務器