Spring cloud服务发现之服务提供者和服务消费者

来源:互联网 发布:淘宝外卖确认送达失败 编辑:程序博客网 时间:2024/05/18 01:32

Spring cloud服务发现之服务提供者和服务消费者


  • 1.服务提供者

  • 2.服务提供者

  • 3.启动运行

  • 4.综上

1.服务提供者


根据上节讲述的服务注册之Eureka注册中心,这节讲述服务提供者和服务消费者,首先新建一个工程,命名为microservice-provider-user,其中pom.xml文件如下:

<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>micorservice-study</artifactId>        <groupId>cn.com</groupId>        <version>1.0-SNAPSHOT</version>    </parent>    <modelVersion>4.0.0</modelVersion>    <artifactId>microservice :: provider :: user</artifactId>    <packaging>jar</packaging>    <name>microservice :: provider :: user</name>    <url>http://maven.apache.org</url>    <properties>        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>    </properties>    <dependencies>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-test</artifactId>            <scope>test</scope>        </dependency>        <dependency>            <groupId>org.springframework.cloud</groupId>            <artifactId>spring-cloud-starter-eureka</artifactId>        </dependency>    </dependencies></project>

ProviderApplication为:

package cn.com.provider;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;/** * Created by xiaxuan on 17/2/26. */@SpringBootApplication@EnableDiscoveryClientpublic class ProviderApplication {    public static void main(String[] args) {        SpringApplication.run(ProviderApplication.class, args);    }}

实体类User:

package cn.com.provider.domain;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;/** * Created by xiaxuan on 17/2/26. */@Data@AllArgsConstructor@NoArgsConstructorpublic class User {    private Long id;    private String username;    private Integer age;}

提供一个service,提供简单的获取User对象的服务,代码为以下:
UserService:

package cn.com.provider.service;import cn.com.provider.domain.User;import org.springframework.stereotype.Service;import java.util.HashMap;import java.util.Map;/** * Created by xiaxuan on 17/2/26. */@Servicepublic class UserService {    private static Map<Long, User> users = new HashMap<>();    static {        users.put(1L, new User(1L, "xiaxuan", 24));        users.put(2L, new User(2L, "bingwen", 24));    }    public User findUserById(Long id) {        return users.get(id);    }}

提供controller为UserController,代码如下:

package cn.com.provider.controllers;import cn.com.provider.domain.User;import cn.com.provider.service.UserService;import org.apache.log4j.BasicConfigurator;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;/** * Created by xiaxuan on 17/2/26. */@RestController@RequestMapping("/user")public class UserController {    private static final Logger LOGGER = LoggerFactory.getLogger(UserController.class);    @Autowired    private UserService userService;    /**     * 目前图简便,就用缺省的配置了     */    static {        BasicConfigurator.configure();    }    @GetMapping("/{id}")    private User findById(@PathVariable Long id) {        User user = userService.findUserById(id);        LOGGER.info("获取用户id为 {} 的用户,详细信息为 {}", id, user);        return user;    }}

启动类ProviderApplication:

package cn.com.provider;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;/** * Created by xiaxuan on 17/2/26. */@SpringBootApplication@EnableDiscoveryClientpublic class ProviderApplication {    public static void main(String[] args) {        SpringApplication.run(ProviderApplication.class, args);    }}

启动类上加上注解@EnableDiscoveryClient,开启服务发现能力。

配置文件为:

server:  port: 8011spring:  application:    name: microservice-provider-usereureka:  client:    serviceUrl:      defaultZone: http://eureka:8000/eureka/  instance:    preferIpAddress: true

标明application名字,运行端口,注册中心地址,具体不再详述了。

2.服务提供者


再次新建一个module,命名为microservice-consumer-user,pom文件和上面消费提供者的一样就不再贴出来了。
启动类ConsumerApplication:

package cn.com.consumer;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;import org.springframework.cloud.client.loadbalancer.LoadBalanced;import org.springframework.context.annotation.Bean;import org.springframework.web.client.RestTemplate;/** * Created by xiaxuan on 17/2/26. */@SpringBootApplication@EnableDiscoveryClientpublic class ConsumerApplication {    @Bean    @LoadBalanced    public RestTemplate restTemplate() {        return new RestTemplate();    }    public static void main(String[] args) {        SpringApplication.run(ConsumerApplication.class, args);    }}

同样,加上@EnableDiscoveryClient,开启服务发现能力,同时提供一个RestTemplate的Bean,因为在spring cloud中,服务之间的调用是通过rest来实现的,等下要使用restTemplate来调用服务提供者提供的服务,在其中有一个注解@LoadBalanced,这个是开启负载均衡使用的,使用到了Ribbon技术,这个放到后面来讲。

实体类不再贴出,其中service ConsumerService为:

package cn.com.consumer.services;import cn.com.consumer.domain.User;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.web.client.RestTemplate;/** * Created by xiaxuan on 17/2/26. */@Servicepublic class ConsumerService {    @Autowired    private RestTemplate restTemplate;    public User findById(Long id) {        return restTemplate.getForObject("http://MICROSERVICE-PROVIDER-USER/user/" + id, User.class);    }}

在以上中,我们调用服务提供者中的地址并不是localhost:8011,而是MICROSERVICE-PROVIDER-USER,这是因为我们开启了服务发现之后可以直接通过服务名来调用服务,而不需要写ip加端口,这样的好处是如果服务提供者是集群模式,就不用调用ip和端口的方式了,同时也能做到负载均衡的能力。

Controller为ConsumerController:

package cn.com.consumer.controllers;import cn.com.consumer.domain.User;import cn.com.consumer.services.ConsumerService;import org.apache.log4j.BasicConfigurator;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;/** * Created by xiaxuan on 17/2/26. */@RestController@RequestMapping("/consumer")public class ConsumerController {    private static final Logger LOGGER = LoggerFactory.getLogger(ConsumerController.class);    @Autowired    private ConsumerService consumerService;    /**     * 采用缺省配置     * */    static {        BasicConfigurator.configure();    }    @GetMapping("/{id}")    public User findById(@PathVariable Long id) {        User user = consumerService.findById(id);        LOGGER.info("获取到的用户id为 {}, User为 {}", id, user);        return user;    }}

比较简单,就是简单的获取user服务。

3.启动运行


启动运行需要有三个模块,分别为:

  • microservice-eureka 注册中心

  • microservice-provider-user 服务提供者

  • microservice-consumer-user 服务消费者

依次按照顺序启动上面三个服务,在浏览器上输入http://eureka:8000,图示如下:


以上注册了两个服务。

现在浏览器上输入:http://localhost:8012/consumer/1,如下:

调用成功。

4.综上


  • 我们再通过服务注册和消费的时候,其实内部还是使用了Ribbon的相关技术,这个放到后面和fegin一起讲。

  • spring cloud服务之间的调用是通过rest的方式完成的,这个的效率相对于使用rpc来说还是要差一点,后面讲怎样将dubbo和dubbox整合起来一起使用。

  • 下一期讲eureka的高可用和服务提供者、服务消费者集群之间的调用方式。

3 0
原创粉丝点击