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

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-studyartifactId>
        <groupId>cn.comgroupId>
        <version>1.0-SNAPSHOTversion>
    parent>
    <modelVersion>4.0.0modelVersion>

    <artifactId>microservice :: provider :: userartifactId>
    <packaging>jarpackaging>

    <name>microservice :: provider :: username>
    <url>http://maven.apache.orgurl>

    <properties>
        <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
    properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-eurekaartifactId>
        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
@EnableDiscoveryClient
public 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
@NoArgsConstructor
public 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.
 */
@Service
public class UserService {

    private static Map 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
@EnableDiscoveryClient
public class ProviderApplication {

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

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

配置文件为:

server:
  port: 8011
spring:
  application:
    name: microservice-provider-user

eureka:
  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
@EnableDiscoveryClient
public 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.
 */
@Service
public 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,图示如下:

Spring cloud服务发现之服务提供者和服务消费者_第1张图片
以上注册了两个服务。

现在浏览器上输入:http://localhost:8012/consumer/1,如下:
Spring cloud服务发现之服务提供者和服务消费者_第2张图片

调用成功。

4.综上


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

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

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

你可能感兴趣的:(springboot,java,微服务,springboot微服务,spring,cloud专题)