SpringCloud--consumer

来源:互联网 发布:软件测试基础理论 编辑:程序博客网 时间:2024/06/03 18:51

继上一篇记录了SpringCloud的服务注册,这一篇继续总结在SpringCloud中服务的发现(如何消费服务)。消费服务的方式有两种,我们可以采用Ribbon和Feign的方式来消费服务。

一、Ribbon

(1)创建一个SpringBoot工程

工程的结构如下:

(2)添加需要的maven依赖

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <groupId>com.hongtu.lahuobao.consumer</groupId>    <artifactId>consumer</artifactId>    <version>1.0.0</version>    <packaging>jar</packaging>    <name>Springcloud - consumer</name>    <description>the demo of springCloud</description>    <parent>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-parent</artifactId>        <version>1.5.2.RELEASE</version>        <relativePath/> <!-- lookup parent from repository -->    </parent>    <properties>        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>        <version.spring>3.2.9.RELEASE</version.spring>        <version.jackson>2.4.4</version.jackson>        <java.version>1.8</java.version>    </properties>    <dependencyManagement>        <dependencies>            <dependency>                <groupId>org.springframework.cloud</groupId>                <artifactId>spring-cloud-dependencies</artifactId>                <version>Brixton.RELEASE</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>    <dependencies>        <dependency>            <groupId>org.springframework.cloud</groupId>            <artifactId>spring-cloud-starter-eureka</artifactId>        </dependency>        <!--Swagger begin-->        <dependency>            <groupId>com.mangofactory</groupId>            <artifactId>swagger-springmvc</artifactId>            <version>0.9.5</version>        </dependency>        <dependency>            <groupId>io.springfox</groupId>            <artifactId>springfox-swagger2</artifactId>            <version>2.6.1</version>        </dependency>        <dependency>            <groupId>io.springfox</groupId>            <artifactId>springfox-swagger-ui</artifactId>            <version>2.6.1</version>        </dependency>        <!--Swagger end-->        <!--SpringCloud begin-->        <dependency>            <groupId>org.springframework.cloud</groupId>            <artifactId>spring-cloud-starter-feign</artifactId>        </dependency>        <dependency>            <groupId>org.springframework.cloud</groupId>            <artifactId>spring-cloud-starter-ribbon</artifactId>            <version>1.3.0.RELEASE</version>        </dependency>        <!--SpringCloud end-->        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-test</artifactId>            <scope>test</scope>        </dependency>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-log4j</artifactId>            <version>1.2.5.RELEASE</version>        </dependency>    </dependencies></project>
注意在这个地方我是将Ribbon和Feign写在一个工程中的,所以在上面的依赖添加中,我添加了Feign和Ribbon的依赖,大家可以根据需要删掉不必要的依赖。

(3)配置文件配置项

spring.application.name=liutao_consumereureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/server.port=8002
上面针对SpringCloud的配置和provider中针对SpringCloud的配置相同,主要将服务注册到注册中心,以方便消费provider中提供的服务。

(4)程序运行主类

package com.liutao.application;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;import org.springframework.context.annotation.ComponentScan;/** * 程序启动类 * * @author LIUTAO * @version 2017/5/23 * @see * @since */@EnableDiscoveryClient@SpringBootApplication@ComponentScan(basePackages={"com.liutao"})public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}}

(5)RestTemplate配置类

在此我们可以设置连接请求时间和连接超时时间等,具体的设置如下:

#RestTemplaterestTemplate.connectionRequestTimeout = 300000restTemplate.connectionTimeout = 300000restTemplate.readTimeout = 300000
配置类如下:

package com.liutao.config;import org.springframework.beans.factory.annotation.Value;import org.springframework.cloud.client.loadbalancer.LoadBalanced;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Primary;import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;import org.springframework.web.client.RestTemplate;/** * 配置RestTemplate * * @author LIUTAO * @version 2017/4/21 * @see * @since */@Configurationpublic class RestTemplateConfig {    @Value("${restTemplate.connectionRequestTimeout}")    private int connectionRequestTimeout; //连接请求超时时间    @Value("${restTemplate.connectionTimeout}")    private int connectionTimeout;        //连接超时时间    @Value("${restTemplate.readTimeout}")    private int readTimeout;              //读取超时时间    @Bean    @LoadBalanced    @Primary    public RestTemplate customRestTemplate(){        HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();        httpRequestFactory.setConnectionRequestTimeout(connectionRequestTimeout);        httpRequestFactory.setConnectTimeout(connectionTimeout);        httpRequestFactory.setReadTimeout(readTimeout);        return new RestTemplate(httpRequestFactory);    }}

我们可以看见上面的bean上有一个@LoadBalanced注解,这个注解主要是为了实现负载均衡。

(6)消费服务提供者提供的服务

/**     * 使用Ribbon实现客户端负载均衡的消费者     * @param username     * @return     */    @RequestMapping(value = "/ribbon/userInfo/{username}",method = RequestMethod.GET)    @ResponseBody    public User getUserInfoOfRibbon(@PathVariable("username") String username) {        User user = restTemplate.getForEntity("http://liutao-provider/liutao/userInfo?username="+username, User.class).getBody();        if(user!=null){            logger.info("user.getAge():"+user.getAge());        }        return user;    }
(7)测试

现在我们运行程序,并调用相应的接口就可以看见程序的运行结果了。

那么这里出现了一个疑问,针对负载均衡,这里到底是如何实现的?又需要如何进行测试呢?

针对这个疑问,我们只需要在RestTemplate上添加@LoadBalanced注解就可以实现消费者对服务提供者提供的服务实现负载均衡的消费。针对测试,我们可以启动两个provider,然后运行consumer,多次调用consumer中相同的接口,就会发现在不是每次都调用的是相同的provider。

二、Feign

在consumer中要调用provider中的服务,除了使用Ribbon之外,我们还可以使用Feign的方法来调用。Feign整合了Ribbon,同时支持负载均衡。

(1)创建一个SpringBoot工程。

工程结构和上面的工程结构是相同的。

(2)添加需要的maven依赖

这里和上面的maven依赖大部分是一样的,就只有一个地方,使用Ribbon和使用Feign需要分别添加自己的maven依赖。

(3)配置文件配置项

和上面一样。

(4)程序运行主类

package com.liutao.application;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;import org.springframework.cloud.netflix.feign.EnableFeignClients;import org.springframework.context.annotation.ComponentScan;/** * 程序启动类 * * @author LIUTAO * @version 2017/5/23 * @see * @since */@EnableFeignClients(basePackages={"com.liutao.controller.client"})@EnableDiscoveryClient@SpringBootApplication@ComponentScan(basePackages={"com.liutao"})public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}}
我们可以看见这个程序运行主类和Ribbon的运行主类相比多了一个@EnablefeignClients注解,这个注解就是启动扫描FeignClient的功能。

(5)Feign client类

package com.liutao.controller.client;import com.liutao.entity.User;import org.springframework.cloud.netflix.feign.FeignClient;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.ResponseBody;@FeignClient(value = "liutao-provider")public interface UserClient {    @RequestMapping(value = "/userInfo",method = RequestMethod.GET)    @ResponseBody    User getUserInfo(@RequestParam("username") String username);}
注意:这个类中方法的书写和标签的使用需要和provider中相应的方法一致。

(6)测试Controller

/**     * 使用Feign     * @param username     * @return     */    @RequestMapping(value = "/feign/userInfo/{username}",method = RequestMethod.GET)    @ResponseBody    public User getUserInfo(@PathVariable("username") String username) {        User user = userClient.getUserInfo(username);        if(user!=null){            logger.info("user.getAge():"+user.getAge());        }        return user;    }
可以看见上面的调用provider中的服务的代码要比使用Ribbon调用provider中的服务的代码要简洁很多。

(7)运行测试

进行测试后我们可以发现使用Feign的方法也可以实现负载均衡。

详细代码请参考gitHub地址:SpringCloud--consumer





原创粉丝点击