SpringCloud——(3)RestTemplate,Feign

服务通信

【一】前言

在springcloud微服务的实际项目开发中,多个微服务之间不仅是相对独立的,而且也是相对关联的;也就是说,微服务之间需要相互访问,多个微服务之间的接口可能会被互相多次调用,我们称之为微服务之间的通信;微服务之间的通信方式有很多。
一般使用以下两种方法:一种是RestTemplate,另一种是Feign;

【二】服务通信的两种方式

  • RestTemplate,是spring中方便使用rest资源的一个对象,交互访问的资源通过URL进行识别和定位,每次调用都使用模板方法的设计模式,模板方法依赖于具体接口的调用,从而实现了资源的交互和调用; 它的交互方法有30多种,大多数都是基于HTTP的方法,比如:delete()、getForEntity()、getForObject()、put()、headForHeaders()等;
  • Feign,一个声明式的伪HTTP客户端,使得编写HTTP客户端更加容易; 它只需要创建一个接口,并且使用注解的方式去配置,即可完成对服务提供方的接口绑定,大大简化了代码的开发量; 同时,它还具有可拔插的注解特性,而且支持feign自定义的注解和springMvc的注解(默认);

【三】RestTemplate进行服务通信


  • 第二步(构建Order项目,Product项目)
    这个地方我就只写如何构建Order项目,Product项目和Order一致,只是Product需要提供一个可进行查询的接口。注意:当前构建的Product和Order两个服务都是采用的多Model的方式构建的,如果有小伙伴对多model构建项目不熟悉的话可以看博客:https://blog.csdn.net/wenge1477/article/details/101865503

    构建order服务:

  1. 创建父项目,添加多个子model
    在这里插入图片描述
  2. 添加maven对应的依赖
    父层的pom.xml文件
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <packaging>pom</packaging>
    <modules>
        <module>comment</module>
        <module>client</module>
        <module>dao</module>
    </modules>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.0.M6</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.feng</groupId>
    <artifactId>order</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>order</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.M2</spring-cloud.version>
        <lombok.version>1.18.8</lombok.version>
        <model.version>0.0.1-SNAPSHOT</model.version>
        <feign.version>1.4.4.RELEASE</feign.version>
        <fastjson.version>1.2.60</fastjson.version>

    </properties>

    <dependencies>
        <!--用于json字符串的转换-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>${fastjson.version}</version>
        </dependency>

        <!--消息总线用于配置的自动刷新-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-amqp</artifactId>
            <version>2.1.1.RELEASE</version>
        </dependency>

        <!--整合RabbitMQ-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>

        <!--整合Redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <!--服务注册-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <!--使用Stream流-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
        </dependency>

        <!--用于从配置中心拉取配置-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-client</artifactId>
        </dependency>

        <!--用于查询数据库-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <!--用于服务于服务之间的通信-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
            <version>${feign.version}</version>
        </dependency>

        <!--服务监控-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zipkin</artifactId>
        </dependency>

        <!--服务熔断-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
            <version>1.4.7.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!--简化get,set-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
            <scope>provided</scope>
        </dependency>

        <!--连接mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>

        <!--检验参数-->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>5.4.1.Final</version>
        </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>
            <dependency>
                <groupId>com.feng</groupId>
                <artifactId>comment</artifactId>
                <version>${model.version}</version>
            </dependency>
            <dependency>
                <groupId>com.feng</groupId>
                <artifactId>dao</artifactId>
                <version>${model.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
        </pluginRepository>
    </pluginRepositories>

</project>

comment模块的pom.xml文件

<?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">
    <parent>
        <artifactId>order</artifactId>
        <groupId>com.feng</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>comment</artifactId>
    
</project>

dao模块的pom.xml文件

<?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">
    <parent>
        <artifactId>order</artifactId>
        <groupId>com.feng</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>dao</artifactId>
    <dependencies>
        <dependency>
            <groupId>com.feng</groupId>
            <artifactId>comment</artifactId>
        </dependency>
    </dependencies>

</project>

client模块的pom.xml文件

<?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">
    <parent>
        <artifactId>order</artifactId>
        <groupId>com.feng</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>client</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <artifactId>dao</artifactId>
            <groupId>com.feng</groupId>
        </dependency>
    </dependencies>

    <build>
        <!--最后打包的名称-->
        <finalName>order</finalName>
        <plugins>
            <!--进行打包-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <!--设置主入口-->
                <configuration>
                    <mainClass>com.feng.order.OrderApplication</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal><!--可以把依赖的包都打包到生成的Jar包中-->
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <configuration>
                    <warName>order</warName>
                </configuration>
            </plugin>

            <!--跳过测试-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <skipTests>true</skipTests>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>
  1. 完成comment层

创建Product实体

@Data
@Entity
public class Product  implements Serializable {
    @Id
    private Integer id;
    private String name;
    private String type;
    private Double price;
}

创建Order实体

@Data
@Entity
public class Order  implements Serializable {

    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private Integer id;

    private String orderNum;

    private String orderDate;

    private Double orderPrice;

    private String orderStatu;
}
  1. 完成dao层使用dataJpa查询数据库

创建OrderRepository
这个地方使用的是dataJpa所以基本的增删改查已经通过继承JpaRepository已经实现有了

@Repository
public interface OrderRepository extends JpaRepository<Order,Integer> {
    

}
  1. 完成service层和Controller层
    这个地方下订单的的service我就不写了,我们主要讲下服务之间的通信问题,有兴趣的小伙伴可以自己去写下相关的逻辑。


    这个地方只写服务调用的Controller:
	/**
     * 第一种获取服务通信的方式RestTemplate直接写死url
     * @return
     */
    @GetMapping("getMessgae")
    public String listProduct(){
        RestTemplate restTemplate = new RestTemplate();
        String message = restTemplate.getForObject("http://localhost:8083/test/msg", String.class);
        return message;
    }
	@Autowired
    private LoadBalancerClient balancerClient;
    /**
     * 第二种获取服务通信的方式LoadBalancerClient
     * @return
     */
    @GetMapping("getMessgae2")
    public String listProduct2(){
        RestTemplate restTemplate = new RestTemplate();
        ServiceInstance instance = balancerClient.choose("PRODUCT");
        String url = String.format("http://%s:%s",instance.getHost(),instance.getPort());
        String message = restTemplate.getForObject(url, String.class);
    }
        
//第三种方式通信
//1、注入bean
@Component
public class RestTemplateConfig {


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

}


//2、在需要的地方进行注入,调用
	 @Autowired
    private  RestTemplate restTemplate;
    /**
     * 第三种获取服务通信的方式
     * @return
     */
    @GetMapping("getMessgae3")
    public String listProduct3(){

        String message = restTemplate.getForObject("http://PRODUCT/test/msg", String.class);
        return message;
	}
  1. 这个地方使用配置在配置中心
    需要在github上的配置项目中添加Order配置文件
    在这里插入图片描述

    如果有小伙伴多统配置中心拉取配置不熟悉的,请看博客:https://blog.csdn.net/wenge1477/article/details/102505658

  • 第三步(Product提供查询商品的服务)
    在这里插入图片描述

【四】Feign进行服务通信

  • 第一步(启动Eureka)

  • 第二步(构建Order项目,Product项目)

  • 第三步(Product提供查询商品的服务)
    前三步和上面使用RestTemplate的一样,具体的查看以上的步骤

  • 第四步(创建Feign调用的接口)

@FeignClient(name = "product")
public interface ProductClient {
    /**
     * 通过商品的id集合去查询商品列表
     * @param listId
     * @return
     */
    @GetMapping("/product/list")
    List<Product> getByIds(@RequestParam("ids")List<Integer> listId);

    /**
     * 通过购物列表,去调用商品服务的减库存的服务
     * @param productInfoList
     */
    @PostMapping("/product/reduce")
    void reduceProductCount(@RequestBody List<ProductInfo> productInfoList);

}
  • 第五步(调用接口进行通信)
@RestController
@RequestMapping("test")
@RefreshScope
public class TestController {
	@Autowired
    private ProductClient productClient;
    
     @Autowired
    private  RestTemplate restTemplate;
    
    @GetMapping("listProduct")
    public List<Product> test(){
        List<Product> productList = productClient.getByIds(Arrays.asList(1,2));
        redisTemplate.opsForValue().set("key", JSON.toJSONString(productList));
        return productList;
    }
}

  • 第六步(启动类上添加注解)
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class OrderApplication {[添加链接描述](https://blog.csdn.net/annotation_yang/article/details/80876913)

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

}

Order服务GitHub地址:https://github.com/fengsri/cloud-order

Product服务GitHub地址:https://github.com/fengsri/cloud-product

【五】链接

https://blog.csdn.net/alan_liuyue/article/details/82773555
https://blog.csdn.net/yeyazhishang/article/details/84344402
https://blog.csdn.net/annotation_yang/article/details/80876913
https://www.jianshu.com/p/8bca50cb11d8

发布了130 篇原创文章 · 获赞 88 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/wenge1477/article/details/102513819