SpringCloud学习1-服务注册中心

316 阅读8分钟

前言

近段时间自己学习了下SpringCloud相关技术,由于Springcloud是一个完整的分布式微服务框架,所包含的技术很多。本文主要介绍SpringCloud环境搭建和各种服务注册中心的使用,以及差异优缺点,仅作为笔记,方便自己以后的复习

版本选择

SpringCloud版本依赖于SpringBoot的版本,可以从官网查询相关版本依赖关系:spring.io/projects/sp…

springboot 2.2.5.RELEASE
springcloud Hoxton.SR3

搭建一个SpringCloud项目

pom依赖

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <junit.version>4.12</junit.version>
        <log4j.version>1.2.17</log4j.version>
        <lombok.version>1.16.18</lombok.version>
        <mysql.version>5.1.47</mysql.version>
        <druid.version>1.1.16</druid.version>
        <mybatis.spring.boot.version>1.3.0</mybatis.spring.boot.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <!--springboot版本-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.2.5.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--springcloud版本-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR3</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--springcloud-alibaba-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.1.0.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--mysql-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <!--druid-->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>${druid.version}</version>
            </dependency>
            <!--junit-->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
                <scope>test</scope>
            </dependency>
            <!--mybatis-springboot-->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis.spring.boot.version}</version>
            </dependency>
            <!--log4j-->
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>${log4j.version}</version>
            </dependency>
            <!--lombok-->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
                <scope>provided</scope>
            </dependency>
            <!--druid-spring-->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>1.1.10</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <!--springboot maven打包插件-->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork>
                    <addResources>true</addResources>
                </configuration>
            </plugin>
        </plugins>
    </build>

服务注册中心

Eureka

Eureka是netflix推出的一款服务注册中心,它是C/S架构的。目前2.0版本已经从github上停更,详细可见 github.com/Netflix/eur…

搭建Eureka Server

项目中创建对应的module

    <dependencies>
        <!--eureka server-->
        <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-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
    </dependencies>

修改application.yml配置文件

server:
  port: 7001

#eureka相关配置
eureka:
  instance:
    hostname: eureka7001.com #本地配置host文件
  client:
    #是否向Eureka中注册。因为本模块是Eureka Server端,不需要注册自己,默认是true
    register-with-eureka: false
    #是否从Eureka检索服务,当前是Server端不需要检索,默认是true
    fetch-registry: false
    service-url:
#      单机版
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka
#      集群版 互相守望
#      defaultZone: http://eureka7002.com:7002/eureka
  server:
#    禁用eureka的自我保护机制
#    enable-self-preservation: false
#    服务维持心跳时间,单位ms
#    expected-client-renewal-interval-seconds: 2000

修改主启动类

@SpringBootApplication
@EnableEurekaServer #启用Eureka Server
public class EurekaServer7001 {

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

测试访问

访问 http://eureka服务器ip:端口

服务提供者

项目中创建对应的module

#端口号配置
server:
  port: 8001

#spring相关配置
spring:
  application:
    name: cloud-payment-service
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: org.gjt.mm.mysql.Driver
    url: jdbc:mysql://localhost:3306/springcloud?useUnicode=true&characterEncoding=utf8&useSSL=false
    username: root
    password: 123456

#mybatis相关配置
mybatis:
  mapper-locations:
    - classpath:mapper/*.xml
  type-aliases-package: com.sun.cloud.pojo
  configuration:
    map-underscore-to-camel-case: true

#mybatis日志打印
logging.level.com.sun.cloud.mapper: debug

#eureka Client相关配置
eureka:
  instance:
#    eureka web端显示主机名称
    instance-id: payment8001
#    显示ip地址
    prefer-ip-address: true
#    eureka向客户端发送心跳的时间,单位:s(默认是30s)
#    lease-renewal-interval-in-seconds: 1
#    eureka服务端在最后一次心跳后的等待时间上限,单位:s(默认是90s),超时将删除服务
#    lease-expiration-duration-in-seconds: 2
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
#      集群版
#      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
#      单机版
      defaultZone: http://localhost:7001/eureka

主启动类

@SpringBootApplication
@EnableEurekaClient //启用eureka client
@EnableDiscoveryClient #启用发现服务客户端
public class PaymentMain8001 {

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

服务消费者

项目中创建对应的module

    <dependencies>
        <!--eureka client-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!--javabean对象包-->
        <dependency>
            <groupId>com.sun</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
    </dependencies>

application.yml配置文件

server:
  port: 80

spring:
  application:
    name: cloud-consumer-order

#eureka相关配置
eureka:
  client:
    fetch-registry: true
    register-with-eureka: true
    service-url:
#      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
      defaultZone: http://localhost:7001/eureka #单机版

主启动类

@SpringBootApplication
@EnableEurekaClient
public class OrderMain80 {

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

自动配置类

@Configuration
public class ApplicationConfig {
    @Bean
    @LoadBalanced // 不添加该注解,在多个服务的时候,出现在报错
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
}

控制层

@RestController
@Slf4j
@RequestMapping("/consumer/payment")
public class OrderController {

    // private static final String PAYMENT_URL = "http://localhost:8001";

    // 服务提供者的服务名
    private static final String APPLICATION_NAME = "http://CLOUD-PAYMENT-SERVICE";

    @Autowired
    RestTemplate restTemplate;

    @GetMapping("/get/{id}")
    public CommonResult get(@PathVariable("id") Integer id) {
        log.info("消费端查询订单");
        return restTemplate.getForObject(APPLICATION_NAME + "/payment/get/" + id, CommonResult.class);
    }
}

Zookeeper

前提准备

centos服务器上安装配置好zookeeper

服务提供者

项目中创建对应的module

    <dependencies>
        <!--zookeeper依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
            <exclusions>
                <!--先排除自带的zookeeper-3.5.3-beta,如果zookeeper不是对应版本,则会提示相关报错-->
                <exclusion>
                    <groupId>org.apache.zookeeper</groupId>
                    <artifactId>zookeeper</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--引入我们按照的zookeeper对应的版本-->
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.10</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
    </dependencies>

修改application.yml配置文件

server:
  port: 8004 #端口自定义

spring:
  application:
    name: cloud-payment-service #服务名自定义
  cloud:
    zookeeper:
#      zookeeper配置
      connect-string: 192.168.126.100:2181 #zookeeper的服务器ip:端口

修改主启动类

@SpringBootApplication
@EnableDiscoveryClient #zookeeper和consul作为注册中心的时候使用该注解
public class PaymentMain8004 {

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

检查zookeeper

发现服务已经注册到zookeeper下,且该服务是临时节点,当服务宕机之后,zookeeper会删除该节点

[zk: localhost:2181(CONNECTED) 4] ls /services/cloud-payment-service                                      
[68849763-dd0a-4b5d-b49c-d038fc25f85e]

服务消费者

项目中创建对应的module

依赖和服务提供者相同

修改application.yml配置文件

server:
  port: 80

spring:
  application:
    name: cloud-consumer-zk-order
  cloud:
    zookeeper:
      connect-string: 192.168.126.100:2181

修改主启动类

@SpringBootApplication
@EnableDiscoveryClient
public class OrderZKMain80 {

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

消费服务

@RestController
@RequestMapping("/consumer/payment")
public class OrderController {

    // 消费提供者注册进zookeeper的服务名
    private static final String APPLICATION_NAME = "http://cloud-payment-service";

    @Autowired
    RestTemplate restTemplate;

    @GetMapping("/zk")
    public String zk() {
        return restTemplate.getForObject(APPLICATION_NAME + "/payment/zk", String.class);
    }
}

Consul

安装

#解压
unzip consul_1.7.2_linux_amd64.zip
#解压后的文件只有一个consul可执行文件
#移动到/usr/local/bin/目录下
mv consul /usr/local/bin/
#执行consul,指定ip运行
consul agent -dev -client 192.168.126.100
#访问地址
http://192.168.126.100:8500

服务提供者

项目中创建对应的module

    <dependencies>
        <!--consul依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <!--javabean对象包-->
        <dependency>
            <groupId>com.sun</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

修改application.yml配置文件

server:
  port: 8006

spring:
  application:
    name: cloud-payment-service
  cloud:
    consul:
      host: localhost #consul的ip地址
      port: 8500 #consul的端口
      discovery:
        service-name: ${spring.application.name} #注册进consul的服务名
      heartbeat:
        health-check-critical-timeout: 10s #过多少秒健康检查不通过,从consul中删除该服务

主启动类

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

服务消费者

依赖同服务提供者

修改application.yml配置文件

server:
  port: 80

spring:
  application:
    name: cloud-consumer-consul-order
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        service-name: ${spring.application.name}

主启动类

同服务提供者相同

三个注册中心的异同点

组件名 语言 CAP 服务健康检查 对外暴露的接口
eureka java AP 可配支持 HTTP
zookeeper java CP 支持 客户端
consule go CP 支持 HTTP、 DNS