SpringCloud入门笔记01:Quick Start

551 阅读2分钟

本文将重点使用Eureka组件构建一个Spring Cloud的基础Demo:springcloud-demo。项目总体结构如下:

  • springcloud-demo
    • user-service
    • eureka-service
    • consumer-demo

一、Eureka概述

Eureka组件是Spring Cloud中的核心组件,充当全局服务注册中心的角色,提供了服务注册、服务发现、服务治理的功能。现在将以最精简的方式展现如下3个工程:user-service(服务提供者)、eureka-server(注册中心)、consumer-demo(服务消费者),来体验一下Spring Cloud的基础使用。

二、项目搭建

2.1 准备工作:新建maven父工程springcloud-demo,并添加依赖

<groupId>cn.zephyr</groupId>
<artifactId>springcloud-demo</artifactId>
<version>1.0-SNAPSHOT</version>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.2.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
    <java.version>1.8</java.version>
    <spring-cloud.version>Hoxton.RELEASE</spring-cloud.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </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>
    </dependencies>
</dependencyManagement>

2.2 搭建一个业务微服务(以user-service为例)

2.2.1 添加maven依赖

<?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>
	<parent>
		<groupId>cn.zephyr</groupId>
		<artifactId>springcloud-demo</artifactId>
		<version>1.0-SNAPSHOT</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>cn.zephyr</groupId>
	<artifactId>user-service</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>user-service</name>
	<description>User Service Module</description>

	<properties>
		<java.version>1.8</java.version>
	</properties>

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

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</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>
		<!--	通用Mapper	-->
		<dependency>
			<groupId>tk.mybatis</groupId>
			<artifactId>mapper-spring-boot-starter</artifactId>
			<version>2.0.2</version>
		</dependency>

	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

2.2.2 添加user-service项目配置

spring.datasource.url=jdbc:mysql://localhost:3306/zephyr_sc
spring.datasource.username=root
spring.datasource.password=111111
spring.application.name=user-service

server.port=8081

2.2.3 添加基础业务代码:

  • SysUserController.java
    @RequestMapping("sysUser")
    @RestController
    public class SysUserController {
    
        @Resource
        private SysUserService sysUserService;
    
        @RequestMapping("selectById")
        public SysUser selectById(Integer id ){
            return sysUserService.selectById(id);
        }
    }
    
  • SysUserService.java
    @Service
    public class SysUserService {
    
        @Resource
        private SysUserMapper sysUserMapper;
    
        /**
        * 根据id查询
        * @param id
        * @return
        */
        public SysUser selectById(Integer id){
            return this.sysUserMapper.selectByPrimaryKey(id);
        }
    }
    
  • SysUserMapper.java
    @Mapper
    public interface SysUserMapper extends tk.mybatis.mapper.common.Mapper<SysUser>{
    }
    
  • SysUser.java
    @Data
    @Table(name = "sys_user")
    public class SysUser {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Integer id;
        // 用户名
        private String username;
    
        // 密码
        private String password;
    
        // 姓名
        private String name;
    
        // 年龄
        private Integer age;
    
        // 性别,1男性,2女性
        private Integer gender;
    
        // 备注
        private String remarks;
    
    }
    
  • 启动类:UserServiceApplication.java
    @SpringBootApplication
    public class UserServiceApplication {
        public static void main(String[] args) {
            SpringApplication.run(UserServiceApplication.class, args);
        }
    }
    
  • 库表结构
    -- auto-generated definition
    create table sys_user
    (
        id       int auto_increment
            primary key,
        username varchar(20)  null,
        password varchar(50)  null,
        name     varchar(20)  null,
        age      int          null,
        gender   int          null,
        remarks  varchar(255) null
    );
    

2.2.4 业务接口测试

// http://localhost:8081/sysUser/selectById?id=1

{
  "id": 1,
  "username": "haha",
  "password": "111111",
  "name": "zhangsan",
  "age": 21,
  "gender": 1,
  "remarks": "11223344"
}

2.3 搭建服务服务注册中心

2.3.1 新建maven子模块eureka-server,并添加依赖:

<parent>
    <groupId>cn.zephyr</groupId>
    <artifactId>springcloud-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<groupId>cn.zephyr</groupId>
<artifactId>eureka-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eureka-server</name>
<description>Eureka Server Module</description>

<properties>
    <java.version>1.8</java.version>
    <spring-cloud.version>Hoxton.RELEASE</spring-cloud.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </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>
</dependencies>

2.3.2 新增配置:application.yml

server:
  port: 7001 # 端口
spring:
  application:
    name: eureka-server # 应用名称,会在Eureka中显示
eureka:
  client:
    register-with-eureka: true # 是否注册自己的信息到EurekaServer,默认是true
    fetch-registry: false # 是否拉取其它服务的信息,默认是true
    service-url: # EurekaServer的地址,现在是自己的地址,如果是集群,需要加上其它Server的地址。
      defaultZone: http://127.0.0.1:7001/eureka

2.3.3 新增启动类

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {

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

}

2.3.4 启动测试

访问地址:http://localhost:7001/

2.4 改造业务微服务(user-service),并注册到eureka-server(以下配置都是针对user-service进行的)

2.4.1 新增maven依赖

<!-- Eureka客户端 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

2.4.2 新增eureka配置

# EurekaServer地址
eureka.client.service-url.defaultZone=http://127.0.0.1:7001/eureka
# 指定自己的ip信息,不指定的话会自己寻找
eureka.instance.prefer-ip-address=true
eureka.instance.ip-address=127.0.0.1

2.4.3 启动类上通过添加@EnableDiscoveryClient来开启Eureka客户端功能

@SpringBootApplication
@EnableDiscoveryClient
public class UserServiceApplication {
	public static void main(String[] args) {
		SpringApplication.run(UserServiceApplication.class, args);
	}
}

2.4.4 启动测试:

访问地址:http://localhost:7001/,可以发现user-service已注册到eureka-server上

2.5 新增服务调用模块(以consumer-demo为例)

2.5.1 新增依赖

<?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>
	<parent>
		<groupId>cn.zephyr</groupId>
		<artifactId>springcloud-demo</artifactId>
		<version>1.0-SNAPSHOT</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>cn.zephyr</groupId>
	<artifactId>consumer-demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>consumer-demo</name>
	<description>consumer-demo module</description>

	<properties>
		<java.version>1.8</java.version>
	</properties>

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

		<!-- Eureka客户端 -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
		</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>

	</dependencies>


	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

2.5.2 新增配置文件

spring.application.name=consumer-name
server.port=8080
# EurekaServer地址
eureka.client.service-url.defaultZone=http://127.0.0.1:7001/eureka,http://127.0.0.1:7002/eureka
# 指定自己的ip信息,不指定的话会自己寻找
eureka.instance.prefer-ip-address=true
eureka.instance.ip-address=127.0.0.1

2.5.3 编写业务代码

  • 配置类:SysConfiguration.java
    @Configuration
    public class SysConfiguration {
    
        @Bean
        public RestTemplate restTemplate(){
            return new RestTemplate();
        }
    }
    
  • controller:SysUserController.java
    @RestController
    @RequestMapping("consumer/sysUser/")
    public class SysUserController {
        @Resource
        private RestTemplate restTemplate;
    
        @Resource
        private DiscoveryClient discoveryClient;
    
        @RequestMapping("selectById")
        public SysUser selectById(Integer id){
            ServiceInstance instance = discoveryClient.getInstances("user-service").get(0);
            String url = "http://"+instance.getHost() + ":" + instance.getPort()+"/user/";
            return restTemplate.getForObject(url,SysUser.class);
        }
    }
    
  • 实体类:UserService
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class SysUser {
        private Integer id;
        // 用户名
        private String username;
    
        // 密码
        private String password;
    
        // 姓名
        private String name;
    
        // 年龄
        private Integer age;
    
        // 性别,1男性,2女性
        private Integer gender;
    
        // 备注
        private String remarks;
    
  • 启动类:ConsumerDemoApplication.java
    @SpringBootApplication
    @EnableDiscoveryClient // 开启Eureka客户端
    public class ConsumerDemoApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ConsumerDemoApplication.class, args);
        }
    }
    

2.5.4 启动后效果

  • 请求consumer-demo中的接口
    // http://localhost:8080/consumer/sysUser/selectById?id=1
    {
    "id": 1,
    "username": "haha",
    "password": "111111",
    "name": "zhangsan",
    "age": 21,
    "gender": 1,
    "remarks": "11223344"
    }
    
  • 访问地址:http://localhost:7001/, 可以发现consumer-demo已注册到eureka-server上

2.5.5 目前的项目结构:

2.6 项目概述

2.6.1 父工程:springcloud-demo

父工程的作用对于子项目的依赖版本管理在Spring Cloud 中尤其重要,Spring Cloud各组件之间的依赖局限于指定的版本,如果每个子组件都单独定义版本,将会非常麻烦且容易出错。为了解决这个问题,Spring Cloud 官方提供了spring-cloud-dependencies,这个依赖内部定义了当前Spring Cloud大版本下各子组件的版本。以F版spring-cloud-dependencies为例,其pom文件中对版本的指定如下

<properties>
    <spring-cloud-kubernetes.version>1.1.0.RELEASE</spring-cloud-kubernetes.version>
    <spring-cloud-security.version>2.2.0.RELEASE</spring-cloud-security.version>
    <spring-cloud-config.version>2.2.0.RELEASE</spring-cloud-config.version>
    <spring-cloud-contract.version>2.2.0.RELEASE</spring-cloud-contract.version>
    <spring-cloud-netflix.version>2.2.0.RELEASE</spring-cloud-netflix.version>
    <spring-cloud-vault.version>2.2.0.RELEASE</spring-cloud-vault.version>
    <spring-cloud-openfeign.version>2.2.0.RELEASE</spring-cloud-openfeign.version>
    <spring-cloud-task.version>2.2.1.RELEASE</spring-cloud-task.version>
    <spring-cloud-stream.version>Horsham.RELEASE</spring-cloud-stream.version>
    <spring-cloud-commons.version>2.2.0.RELEASE</spring-cloud-commons.version>
    <spring-cloud-build.version>2.2.0.RELEASE</spring-cloud-build.version>
    <spring-cloud-zookeeper.version>2.2.0.RELEASE</spring-cloud-zookeeper.version>
    <spring-cloud-consul.version>2.2.0.RELEASE</spring-cloud-consul.version>
    <spring-cloud-bus.version>2.2.0.RELEASE</spring-cloud-bus.version>
    <spring-cloud-function.version>3.0.0.RELEASE</spring-cloud-function.version>
    <spring-cloud-sleuth.version>2.2.0.RELEASE</spring-cloud-sleuth.version>
    <spring-cloud-gateway.version>2.2.0.RELEASE</spring-cloud-gateway.version>
    <spring-cloud-gcp.version>1.2.0.RELEASE</spring-cloud-gcp.version>
    <spring-cloud-cloudfoundry.version>2.2.0.RELEASE</spring-cloud-cloudfoundry.version>
    <main.basedir>${basedir}/../..</main.basedir>
    <spring-cloud-circuitbreaker.version>1.0.0.RELEASE</spring-cloud-circuitbreaker.version>
    <spring-cloud-aws.version>2.2.0.RELEASE</spring-cloud-aws.version>
    <spring-cloud-cli.version>2.2.0.RELEASE</spring-cloud-cli.version>
</properties>

2.6.2 注册中心:eureka-server

注册中心的概念很容易理解,项目中做的事情就是在启动类上添加@EnableEurekaServer注解以开启服务治理,然后添加如下配置,主要是指定注册中心的访问地址,目前是自己注册自己的,注册中心也可以不注册自己。

eureka:
  client:
    register-with-eureka: true # 是否注册自己的信息到EurekaServer,默认是true
    fetch-registry: false # 是否拉取其它服务的信息,默认是true
    service-url: # EurekaServer的地址,现在是自己的地址,如果是集群,需要加上其它Server的地址。
      defaultZone: http://127.0.0.1:7001/eureka
  instance:
    prefer-ip-address: true # 当其它服务获取地址时提供ip而不是hostname
    ip-address: 127.0.0.1 # 指定自己的ip信息,不指定的话会自己寻找

2.6.3 服务提供方:user-service

这个就是一个比较常规的微服务,除了基础业务之外,只是针对Spring Cloud做了如下3个改动

  • 添加eureka-client加依赖
  • 启动类上添加@EnableDiscoveryClient注解,使其能够将自己注册到Eureka Server、能够从Eureka Server拉取服务列表并调用
  • 配置Eureka Server地址
    # EurekaServer地址
    eureka.client.service-url.defaultZone=http://127.0.0.1:7001/eureka,http://127.0.0.1:7002/eureka
    # 指定自己的ip信息,不指定的话会自己寻找
    eureka.instance.prefer-ip-address=true
    eureka.instance.ip-address=127.0.0.1
    

整体很简单,就不赘述了。

2.6.4 服务调用方:consumer-demo

服务调用方做的事情就是从Eureka Server拉取服务列表并调用,落实到代码上,主要体现在这些地方:

  • RestTemplate提交到IOC容器
  • 使用DiscoveryClient从Eureka Server拉取服务列表并选取第一个服务实例进行调用
  • 新增配置,指定EurekaServer地址

2.7 END

至此,我们完成了SpringCloud的最基础使用,接下来,将系统地学习SpringCould的各大组件。