springcloud--part2 : 服务消费者(rest+ribbon)

摘自  方志朋博客(http://blog.csdn.net/forezp/article/details/69788938) ;

在微服务架构中,业务都会被拆成一个个独立的服务,服务与服务的通讯是基于http restful 的;

spring cloud调用服务有两种方式,一种是Ribbon+RestTemplate, 另外一种是Feign。
Ribbon是一个基于HTTP和TCP客户端的负载均衡器,其实feign也使用了ribbon, 只要使用@FeignClient时,ribbon就会自动使用。

先梳理一下 ribbon + restTemplate ;

一. ribbon  简介 

 
Ribbon is a client side load balancer which gives you a lot of control over the behaviour of HTTP and TCP clients. Feign already uses Ribbon, so if you are using @FeignClient then this section also applies.

 —–摘自官网

二.准备

  ribbon的作用是用于负载均衡,所以必须要有服务发现组件。同案例eureka

  2.1  建立服务注册中心 eureka-server;端口:8761;启动工程;

  2.2   创建服务提供者  eureka-client,name为:service-hi ; 端口:8762;启动工程;

  2.3  将service-hi的端口号改成8763,启动工程;

  (在运行框的右下角有一个向下的三角形,点开,选择 edit configuration--将右上角的single instance only勾选掉,就可以同时运行两个不同端口的同名服务)

  此时,运行 http://localhost:8761,可以看到上面同时注册了名为service-hi的两个服务;

  

三. 建立服务消费者

  3.1   新建一个springboot 的module,取名为 service-ribbon;

  3.2   导包(勾选上web + cloud discovery / Eureka Discovery 即可少导这两个包)

    

		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-ribbon</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

	</dependencies>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>${spring-cloud.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

   3.3  配置其applicationyaml  ;名称 service-ribbon  端口:8764;如下:    

server:
  port: 8764

spring:
  application:
    name: service-ribbon

eureka:
  client:
    serviceUrl:
      defaultzone: http://localhost:8761/eureka/

    3.4  在工程的启动类中 通过@EnableDiscoveryClient 向服务中心注册服务; 注入bean:RestTemplate; 通过@LoadBalanced注解表明这个restTemplate开启负载均衡功能;

  

  @SpringBootApplication
  @EnableDiscoveryClient
  public class SpringCloudServiceRibbonApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringCloudServiceRibbonApplication.class, args);
	}

	@Bean
	@LoadBalanced
	RestTemplate restTemplate(){
		return new RestTemplate();
	}
}

    3.5  写一个测试类HelloService,通过注入容器的restTemplate来消费service-hi服务的 /hi 接口。(此处我们直接用程序名service-hi代替了具体的url地址,在ribbon中它会根据服务名来选择具体的服务实例,根据服务实例在请求的时候会用具体的url替换服务名)(注意:SERVICE-HI 服务名必须大写

@Service
public class HelloService {

    @Autowired
    private RestTemplate restTemplate;

    public String hiService(String name){
        return restTemplate.getForObject("http://SERVICE-HI/hi?name="+name,String.class);
    }
}

    3.6  写一个controller,在controller中调用service的方法

@RestController
public class HelloController {

    @Autowired
    HelloService helloService;

    @RequestMapping("/hi")
    public String hi(@RequestParam String name){
        return helloService.hiService(name);
    }
}

    3.7  测试 : 在浏览器中多次访问  http://localhost:8764/hi?name=zdj , 浏览器会交替出现 :

hi, i am from port : 8763
hi, i am from port : 8762

  这说明,当我们通过调用 restTemplate.getForObject("http://SERVICE-HI/hi?name="+name,String.class)的方法时,已经做了负载均衡,访问了不同的端口的服务实例。

    3.8  分析

    

  一个服务注册中心,eureka server,端口为8761
  service-hi工程跑了两个实例,端口分别为8762,8763,分别向服务注册中心注册
  sercvice-ribbon端口为8764,向服务注册中心注册
  当sercvice-ribbon通过restTemplate调用service-hi的hi接口时,因为用ribbon进行了负载均衡,会轮流的调用service-hi:8762和8763 两个端口的hi接口; 

注:

    在service中调用restTemplate.getForObject("http://SERVICR-HI/hi?name="+name,String.class)时候,访问路径注意写清楚,而且 SERVICE-HI必须大写!

    restTemplate.getForObject("http://SERVICR-HI/hi?name="+name,String.class)  标注部分指的是eureka-client的访问路径,如果在测试ribbon的@RequestMapping("/hello"),此处的写法仍然是 /hi (因为eureka-client 的是访问路径没变,仍是 http:// ip:port/hi )   

原文地址:https://www.cnblogs.com/zdj-/p/8250915.html