您好,登录后才能下订单哦!
声明式Web服务客户端:Feign
声明式:接口声明、Annotation驱动
Web服务:HTTP的方式作为通讯协议
客户端:用于服务调用的存根
Feign:原生并不是Spring Web MVC的实现,基于JAX-RS(Java REST 规范)实现。Spring Cloud封装了Feign,使其支持Spring Web MVC。RestTemplate、HttpMessageConverter
RestTemplate以及Spring Web MVC可以显式地自定义HTTPMessageConverter实现。
假设,有一个Java接口PersonService,Feign可以将其声明它是一种HTTP方式调用的。
注册中心(Eureka Server):服务发现和注册
应用名称:spring-cloud-eureka-server
application.properties:
spring.application.name=eureka-server
server.port=12345
##\u53D6\u6D88\u670D\u52A1\u5668\u81EA\u6211\u6CE8\u518C
eureka.client.register-with-eureka=false
##\u4E0D\u9700\u8981\u68C0\u7D22\u670D\u52A1
eureka.client.fetch-registry=false
management.endpoints.web.exposure.include=*
Feign声明接口(契约):定义一种Java强类型接口
模块:person-api
Person
public class Person {
private Long id ;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
PersonService
@FeignClient(value = "person-service")//服务方应用的名称
public interface PersonService {
@PostMapping("/person/save")
boolean save(@RequestBody Person person);
@GetMapping("/person/findall")
Collection findAll();
}
Feign客户(服务消费)端:调用Feign声明接口
应用名称:person-client
依赖:person-api
创建客户端Controller
@RestController
public class PersonServiceController implements PersonService{
private final PersonService personService;
@Autowired
public PersonServiceController(PersonService personService) {
this.personService = personService;
}
@PostMapping("/person/save")//实现了PersonService接口后可以不用写mapping地址
@Override
public boolean save(@RequestBody Person person) {
return personService.save(person);
}
@GetMapping("/person/findall")
@Override
public Collection findAll() {
return personService.findAll();
}
}
创建启动类
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients(clients = PersonService.class)
public class FeignClientBootStrapApplication {
public static void main(String[] args) {
SpringApplication.run(FeignClientBootStrapApplication.class, args);
}
}
配置application.properties
spring.application.name=person-client
server.port=8080
management.endpoints.web.exposure.include=*
eureka.client.serviceUrl.defaultZone=http://localhost:12345/eureka
Feign服务(服务提供)端:不一定强制实现Feign声明接口
应用名称:person-service
依赖:person-api
创建PersonServiceController
@RestController
public class PersonServiceController implements PersonService{
private final ConcurrentHashMap map = new ConcurrentHashMap();
@PostMapping("/person/save")//实现了PersonService接口后可以不用写mapping地址
@Override
public boolean save(@RequestBody Person person) {
return map.put(person.getId(), person) == null;
}
@GetMapping("/person/findall")
@Override
public Collection findAll() {
return map.values();
}
}
创建服务端启动类
@SpringBootApplication
@EnableEurekaClient
public class FeignServiceBootStrapApplication {
public static void main(String[] args) {
SpringApplication.run(FeignServiceBootStrapApplication.class, args);
}
}
配置application.properties
spring.application.name=person-service
server.port=9090
management.endpoints.web.exposure.include=*
eureka.client.serviceUrl.defaultZone=http://localhost:12345/eureka
Feign客户(服务消费)端、Feign服务(服务提供)端,以及Feign声明接口(契约)存放在同一个工程目录。
调用顺序
浏览器 ->person-client->person-service
person-api定义了@FeignClients(value="person-service"),person-service实际是一个服务器提供方的应用名称。
person-client 可以感知person-service应用存在的,并且Spring Cloud帮助解析PersonService中声明的应用名称:
“person-service”,因此person-client在调用PersonService服务时,实际就路由到person-service的URL
整合Netflix Ribbon无锡人流多少钱 http://www.bhnnk120.com/
关闭Eureka注册
调整person-client关闭Eureka
ribbon.eureka.enabled = false
定义服务ribbon的服务列表(服务名称:person-service)
person-service.ribbon.listOfServers = http://localhost:9090,http://localhost:9090,http://localhost:9090
完全取消Eureka注册
将其注释掉 //@EnableEurekaClient
自定义Ribbon的规则
接口和Netfilx内部实现
IRule
随机规则:RandomRule
最可用规则:BestAvailableRule
轮询规则:RoundRobinRule
重试实现:RetryRule
客户端配置:ClientConfigEnableRoundRobinRule
可用性过滤规则:AvailabilityFilteringRule
RT权重规则:WeightedResponseTimeRule
规避区域规则:ZoneAvoidanceRule
实现IRule
public class MyRule extends RandomRule{
@Override
public void initWithNiwsConfig(IClientConfig clientConfig) {
}
@Override
public Server choose(Object key) {
ILoadBalancer balancer = getLoadBalancer();
List allServers = balancer.getAllServers();
//默认只返回第一个服务
return allServers.get(0);
}
}
暴露自定义实现为Spring Bean
@Bean
public MyRule myRule() {
return new MyRule();
}
激活配置
@RibbonClient(value = "person-service",configuration = MyRule.class)
验证结果
[localhost:9090, localhost:9090, localhost:9090]
整合Netflix Hystrix
调整Feign接口
@FeignClient(value = "person-service" ,fallback = PersonServiceFallBack.class)//服务方应用的名称
public interface PersonService {
@PostMapping("/person/save")
boolean save(@RequestBody Person person);
@GetMapping("/person/findall")
Collection findAll();
}
添加Fallback实现
public class PersonServiceFallBack implements PersonService{
@Override
public boolean save(Person person) {
return false;
}
@Override
public Collection findAll() {
return Collections.emptyList();
}
}
调整客户端激活Hystrix
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients(clients = PersonService.class)
@RibbonClient(value = "person-service",configuration = MyRule.class)
@EnableHystrix
public class FeignClientBootStrapApplication {
public static void main(String[] args) {
SpringApplication.run(FeignClientBootStrapApplication.class, args);
}
@Bean
public MyRule myRule() {
return new MyRule();
}
}
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。