1.服务提供者
2.服务提供者
3.启动运行
4.综上
根据上节讲述的服务注册之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名字,运行端口,注册中心地址,具体不再详述了。
再次新建一个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服务。
启动运行需要有三个模块,分别为:
microservice-eureka 注册中心
microservice-provider-user 服务提供者
microservice-consumer-user 服务消费者
依次按照顺序启动上面三个服务,在浏览器上输入http://eureka:8000,图示如下:
现在浏览器上输入:http://localhost:8012/consumer/1,如下:
调用成功。
我们再通过服务注册和消费的时候,其实内部还是使用了Ribbon的相关技术,这个放到后面和fegin一起讲。
spring cloud服务之间的调用是通过rest的方式完成的,这个的效率相对于使用rpc来说还是要差一点,后面讲怎样将dubbo和dubbox整合起来一起使用。
下一期讲eureka的高可用和服务提供者、服务消费者集群之间的调用方式。