您好,登錄后才能下訂單哦!
聲明式Web服務(wù)客戶端:Feign
聲明式:接口聲明、Annotation驅(qū)動
Web服務(wù):HTTP的方式作為通訊協(xié)議
客戶端:用于服務(wù)調(diào)用的存根
Feign:原生并不是Spring Web MVC的實(shí)現(xiàn),基于JAX-RS(Java REST 規(guī)范)實(shí)現(xiàn)。Spring Cloud封裝了Feign,使其支持Spring Web MVC。RestTemplate、HttpMessageConverter
RestTemplate以及Spring Web MVC可以顯式地自定義HTTPMessageConverter實(shí)現(xiàn)。
假設(shè),有一個Java接口PersonService,F(xiàn)eign可以將其聲明它是一種HTTP方式調(diào)用的。
注冊中心(Eureka Server):服務(wù)發(fā)現(xiàn)和注冊
應(yīng)用名稱: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強(qiáng)類型接口
模塊: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")//服務(wù)方應(yīng)用的名稱
public interface PersonService {
@PostMapping("/person/save")
boolean save(@RequestBody Person person);
@GetMapping("/person/findall")
Collection findAll();
}
Feign客戶(服務(wù)消費(fèi))端:調(diào)用Feign聲明接口
應(yīng)用名稱:person-client
依賴:person-api
創(chuàng)建客戶端Controller
@RestController
public class PersonServiceController implements PersonService{
private final PersonService personService;
@Autowired
public PersonServiceController(PersonService personService) {
this.personService = personService;
}
@PostMapping("/person/save")//實(shí)現(xiàn)了PersonService接口后可以不用寫mapping地址
@Override
public boolean save(@RequestBody Person person) {
return personService.save(person);
}
@GetMapping("/person/findall")
@Override
public Collection findAll() {
return personService.findAll();
}
}
創(chuàng)建啟動類
@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服務(wù)(服務(wù)提供)端:不一定強(qiáng)制實(shí)現(xiàn)Feign聲明接口
應(yīng)用名稱:person-service
依賴:person-api
創(chuàng)建PersonServiceController
@RestController
public class PersonServiceController implements PersonService{
private final ConcurrentHashMap map = new ConcurrentHashMap();
@PostMapping("/person/save")//實(shí)現(xiàn)了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();
}
}
創(chuàng)建服務(wù)端啟動類
@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客戶(服務(wù)消費(fèi))端、Feign服務(wù)(服務(wù)提供)端,以及Feign聲明接口(契約)存放在同一個工程目錄。
調(diào)用順序
瀏覽器 ->person-client->person-service
person-api定義了@FeignClients(value="person-service"),person-service實(shí)際是一個服務(wù)器提供方的應(yīng)用名稱。
person-client 可以感知person-service應(yīng)用存在的,并且Spring Cloud幫助解析PersonService中聲明的應(yīng)用名稱:
“person-service”,因此person-client在調(diào)用PersonService服務(wù)時,實(shí)際就路由到person-service的URL
整合Netflix Ribbon無錫人流多少錢 http://www.bhnnk120.com/
關(guān)閉Eureka注冊
調(diào)整person-client關(guān)閉Eureka
ribbon.eureka.enabled = false
定義服務(wù)ribbon的服務(wù)列表(服務(wù)名稱:person-service)
person-service.ribbon.listOfServers = http://localhost:9090,http://localhost:9090,http://localhost:9090
完全取消Eureka注冊
將其注釋掉 //@EnableEurekaClient
自定義Ribbon的規(guī)則
接口和Netfilx內(nèi)部實(shí)現(xiàn)
IRule
隨機(jī)規(guī)則:RandomRule
最可用規(guī)則:BestAvailableRule
輪詢規(guī)則:RoundRobinRule
重試實(shí)現(xiàn):RetryRule
客戶端配置:ClientConfigEnableRoundRobinRule
可用性過濾規(guī)則:AvailabilityFilteringRule
RT權(quán)重規(guī)則:WeightedResponseTimeRule
規(guī)避區(qū)域規(guī)則:ZoneAvoidanceRule
實(shí)現(xiàn)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();
//默認(rèn)只返回第一個服務(wù)
return allServers.get(0);
}
}
暴露自定義實(shí)現(xiàn)為Spring Bean
@Bean
public MyRule myRule() {
return new MyRule();
}
激活配置
@RibbonClient(value = "person-service",configuration = MyRule.class)
驗(yàn)證結(jié)果
[localhost:9090, localhost:9090, localhost:9090]
整合Netflix Hystrix
調(diào)整Feign接口
@FeignClient(value = "person-service" ,fallback = PersonServiceFallBack.class)//服務(wù)方應(yīng)用的名稱
public interface PersonService {
@PostMapping("/person/save")
boolean save(@RequestBody Person person);
@GetMapping("/person/findall")
Collection findAll();
}
添加Fallback實(shí)現(xiàn)
public class PersonServiceFallBack implements PersonService{
@Override
public boolean save(Person person) {
return false;
}
@Override
public Collection findAll() {
return Collections.emptyList();
}
}
調(diào)整客戶端激活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();
}
}
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。