概述
前言
题目本想写服务消费者,可是又怕太强调消费者三个字,因为在Eureka中服务消费者同样也可以作为服务生产者来提供服务,所以这里只写了服务消费。Eureka的服务消费有两种方式,一种是rest+ribbon的方式,另一种是Feign的方式。
Rest+Ribbon
像上一篇博客所讲,创建一个Spring Boot项目,添加Ribbon的引用;如果是Spring Boot1.0,则添加Ribbon引用为:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
如果使用的Spring Boot2.0,Ribbon引用的id不同,添加Ribbon引用为:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
在application.properties文件中添加配置:
server.port=8765
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
spring.application.name=consumer-ribbon
在启动类上添加注解@EnableEurekaClient,实现向Eureka Server的注册,并用Bean的方式注入RestTemplate,如下所示:
@SpringBootApplication
@EnableDiscoveryClient
@RestController
public class ConsumerRibbonApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerRibbonApplication.class, args);
}
@Bean
@LoadBalanced
RestTemplate restTemplate(){
return new RestTemplate();
}
@Autowired
private HelloService helloService;
@GetMapping(value = "/ribbon/sayHello")
public String hello(String name){
return helloService.hiService(name);
}
}
这里没有创建Controller层,直接将启动类注解为Controller,具体的业务逻辑放在Service的实现中。Service所做的,就是根据要调用的服务地址调用生产者的服务:
@Service
public class HelloServiceImpl implements HelloService{
@Autowired
RestTemplate restTemplate;
@Override
public String hiService(String name) {
return restTemplate.getForObject("http://EUREKA-PRODUCER-HELLO/hello?name="+name,String.class);
}
}
如上述代码所示,Eureka在调用生产者服务时,只需要使用服务名称即可,Ribbon会根据注册该服务名的机器进行负载均衡。我所注册的EUREKA-PRODUCER-HELLO名称的机器有两台,用port来区分,在调用时打印机器的端口号。启动consumer-ribbon时,访问多次即可看到输出的端口号的变化,即代表是多个服务生产者提供服务的。
Ribbon是客户端负载,已经默认实现了以下所示的配置Bean:
Bean Type | Bean Name | Class Name |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Feign
利用这种方式调用,同样按上一篇博客介绍创建Spring Boot项目,然后添加Feign的依赖,同样Spring Boot1.0和Spring Boot2.0的引用方式不同,下面是2.0的引用:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
同样的在启动类上添加注解@EnableEurekaClient以注册到Eureka Server上,并添加@EnableFeignClients的注解,代表使用Feign的方式调用服务生产者,如下所示:
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@RestController
public class ConsumerFeignApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerFeignApplication.class, args);
}
@Autowired
private HelloServiceFeignClient helloServiceFeignClient;
@GetMapping(value = "/feign/sayHello")
public String sayHello(@RequestParam("name") String name){
return helloServiceFeignClient.sayHello(name);
}
}
上面代码中的HelloServiceFeignClient是一个接口,用来调用其他服务,以类似于Restful的风格来调用:
@FeignClient(value = "EUREKA-PRODUCER-HELLO")
@Component
public interface HelloServiceFeignClient {
/**
* 打招呼
* @param name
* @return
*/
@GetMapping(value = "/hello")
String sayHello(@RequestParam("name") String name);
}
@FeignClient注解中的value代表要访问的服务名称,下面方法中的url代表访问服务的url,@GetMapping的注解也可使用@RequestMapping(method = RequestMethod.GET)注解代替,post调用方式也一样。对于参数来说,@RequestParam中的value要和服务方的参数名称对应,如果传入多个参数,可以使用@RequestBody注解实体来实现。
FeignClient默认继承了Ribbon,所以这种调用方式的负载均衡也是Ribbon实现的。另外,如果一个服务中要调用多个服务时,课创建多个interface类,只要将@FeignClient的value改成相应的服务名即可,这样注入不同的interface即可调用不同服务中的方法。
后语
个人认为FeignClient的方式还是比较好用,习惯了Restful的调用方式,感觉FeignClient的方式很顺眼也很方便,而且合作开发时代码风格也比较统一。如果服务提供方提供了jar包就更好了,连interface都不用写了,直接使用对方的jar包来调用Eureka服务,而且还可以使用对方的返回实体,自己动手的地方简直太少了。只不过这样的话,自己的服务还是要注册到EurekaServer上才行,因为毕竟还是通过FeignClient的方式调用。
最后
以上就是鲜艳万宝路为你收集整理的Spring Cloud Netflix — 服务消费前言Rest+RibbonFeign后语的全部内容,希望文章能够帮你解决Spring Cloud Netflix — 服务消费前言Rest+RibbonFeign后语所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复