①服务降级。
什么是服务降级:
整体资源快不够了,忍痛将某些服务先关掉,待渡过难关,再开启回来。
服务降级处理是在客户端(服务消费者、服务调用方)实现完成的,与服务端(服务提供者)没有关系。
服务熔断的坏处:容易方法膨胀。增加一个方法,就要增加一个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了,但是我们做了服务降级处理,让客户端在服务端不可用时也会获得提示信息而不会挂起耗死服务器