本文使用生产端与消费端两个工程来展示微服务之间的调用方式
具体内容详见代码注释
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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.cloud.demo</groupId>
<artifactId>micro-provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>micro-provider</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<!--spring cloud依赖管理-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<!--引入zookeeper 测试时使用,只能连接本地的zookeeper-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-all</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.12</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</build>
</project>
application.yml配置
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql:///testdb?useSSL=true
username: root
password: 123
application:
name: provider #配置服务名
cloud:
zookeeper:
connect-string: localhost:2181 #注册zookeeper地址
mybatis:
configuration:
map-underscore-to-camel-case: true # 配置mybatis字段与实体类属性映射
# 配置打印SQL的日志
logging:
level:
com.cloud.demo.microprovider.mapper: debug
UserInfo实体类
package com.cloud.demo.microprovider.domain;
import lombok.Getter;
import lombok.Setter;
import java.util.Date;
@Getter //lombok插件生成get方法
@Setter //lombok插件生成set方法
public class UserInfo {
private Integer userId;
private String userName;
private int userAge;
private Date userBirth;
}
service接口
package com.cloud.demo.microprovider.service;
import com.cloud.demo.microprovider.domain.UserInfo;
public interface UserService {
UserInfo getUserById(Integer userId);
}
service实现类
package com.cloud.demo.microprovider.service;
import com.cloud.demo.microprovider.domain.UserInfo;
import com.cloud.demo.microprovider.mapper.UserInfoMapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class UserServiceImpl implements UserService {
@Resource
private UserInfoMapper userMapper;
@Override
public UserInfo getUserById(Integer userId) {
return userMapper.getUser(userId);
}
}
Mapper
package com.cloud.demo.microprovider.mapper;
import com.cloud.demo.microprovider.domain.UserInfo;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
public interface UserInfoMapper {
@Select("SELECT USER_ID, " +
"USER_NAME, USER_AGE, " +
"USER_BIRTH FROM T_USER WHERE USER_ID=#{userId}")
UserInfo getUser(@Param("userId") Integer userId);
}
Controller
package com.cloud.demo.microprovider.controller;
import com.cloud.demo.microprovider.domain.UserInfo;
import com.cloud.demo.microprovider.service.UserService;
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.RestController;
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("user/{id}")
public UserInfo getUser(@PathVariable("id") Integer userId) {
return userService.getUserById(userId);
}
}
服务启动类:
package com.cloud.demo.microprovider;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@MapperScan("com.cloud.demo.microprovider.mapper")//扫描Mapper到Spring容器中
@EnableDiscoveryClient //将服务注册到Zookeeper中管理
public class MicroProviderApplication {
public static void main(String[] args) {
SpringApplication.run(MicroProviderApplication.class, args);
}
}
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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.gerry.cloud.demo</groupId>
<artifactId>micro-consumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>micro-consumer</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<!--spring cloud依赖管理-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--引入zookeeper 测试时使用,只能连接本地zookeeper-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-all</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.12</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</build>
</project>
application.yml配置
server:
port: 8888 #为了与生成端端口不同,设置端口号
spring:
cloud:
zookeeper:
connect-string: localhost:2181 #注册zookeeper地址
discovery:
register: false #设置为false代表不会注册进zookeeper
实体类
package com.gerry.cloud.demo.microconsumer.vo;
import com.fasterxml.jackson.annotation.JsonAlias;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Getter;
import lombok.Setter;
import java.util.Date;
@Getter
@Setter
public class UserVo {
private Integer userId;
@JsonAlias("userName") // 配置json字段映射
private String personName;
private int userAge;
@JsonFormat(pattern = "yyyy-MM-dd")
private Date userBirth;
}
package com.gerry.cloud.demo.microconsumer.config;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
/**
* 把RestTemplate对象装配到spring容器管理
*/
@SpringBootConfiguration
public class RestTemplateConfiguration {
@Bean
@LoadBalanced //负载均衡
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
Controller
package com.gerry.cloud.demo.microconsumer.controller;
import com.gerry.cloud.demo.microconsumer.vo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class UserWarpController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private LoadBalancerClient loadBalancerClient;
// 写死访问api方式测试
/*@GetMapping("warp/user/{version}/{id}")
public UserVo getUser(@PathVariable("version") double version
, @PathVariable("id") Integer userId, String name) {
System.out.println(version);
System.out.println(name);
// url必须是rest风格路径
return restTemplate.getForObject("http://localhost:8080//user/"+userId, UserVo.class);
}*/
/*@GetMapping("warp/user/{id}")
public UserVo getUser(@PathVariable("id") Integer userId) { //可以实现负载均衡
ServiceInstance serviceInstance = loadBalancerClient.choose("provider");
String host = serviceInstance.getHost(); // 主机名
int port = serviceInstance.getPort(); // 端口号
String url = String.format("http://%s:%s/%s/%d",host, port, "user", userId);
System.out.println(url);
// url必须是rest风格路径
return restTemplate.getForObject(url, UserVo.class);
}*/
@GetMapping("warp/user/{id}") //可以实现负载均衡
public UserVo getUser(@PathVariable("id") Integer userId) {
// url必须是rest风格路径
return restTemplate.getForObject("http://provider/user/"+userId, UserVo.class);
}
}
服务启动类
package com.gerry.cloud.demo.microconsumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class MicroConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(MicroConsumerApplication.class, args);
}
}
注意:此篇文章只是测试时使用,只能连接本地zookeeper,不能连接远程zookeeper,原因是zookeeper依赖不对,应改为:
<!--Service Discovery with Zookeeper-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
</dependency>