SpringCloud:服务提供者集群化及使用Ribbon实现负载均衡

郎家岭伯爵 2022年06月13日 279次浏览

背景

前面我们实现了Eureka注册中心的集群,这里我们来将服务提供者进行集群化,并通过Ribbon实现负载均衡。

实现

本文是基于上一篇的代码来进行的。

服务提供者集群搭建及简单的负载均衡实现。

springcloud-consumer-dept-80

修改pom.xml

添加EurekaClient依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
    <version>1.4.6.RELEASE</version>
</dependency>

修改application.yaml

server:
  port: 80

eureka:
  client:
    register-with-eureka: false # 不向Eureka注册自己
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/

修改启动类

修改ConfigBean

ConfigBean类上的getRestTemplate()方法上添加@LoadBalanced注解,实现RestTemplate的负载均衡。

@LoadBalanced实现负载均衡即为Ribbon的作用!

修改DeptConsumerController

重启模块

至此,我们的服务已经实现了简单的负载均衡。

不过此时我们的服务提供者springcloud-provider-dept-8001只有一个,无法很好地观察到负载均衡的效果。因此接下来我们将把服务提供者集群化,来更好地观察下负载均衡的效果。

新建数据库

数据库在此前数据库的基础上,新建如下两个数据库及对应的数据表:

CREATE DATABASE `db02`;

USE `db02`;

DROP TABLE IF EXISTS `dept`;

CREATE TABLE `db02`.`dept` (
  `deptno` bigint(20) NOT NULL AUTO_INCREMENT,
  `dname` varchar(60) DEFAULT NULL,
  `db_source` varchar(60) DEFAULT NULL,
  PRIMARY KEY (`deptno`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='部门表';

INSERT into dept (dname,db_source) VALUES('开发部',DATABASE());
INSERT into dept (dname,db_source) VALUES('人事部',DATABASE());
INSERT into dept (dname,db_source) VALUES('财务部',DATABASE());
INSERT into dept (dname,db_source) VALUES('市场部',DATABASE());
INSERT into dept (dname,db_source) VALUES('运维部',DATABASE());
CREATE DATABASE `db03`;

USE `db03`;

DROP TABLE IF EXISTS `dept`;

CREATE TABLE `db03`.`dept` (
  `deptno` bigint(20) NOT NULL AUTO_INCREMENT,
  `dname` varchar(60) DEFAULT NULL,
  `db_source` varchar(60) DEFAULT NULL,
  PRIMARY KEY (`deptno`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='部门表';

INSERT into dept (dname,db_source) VALUES('开发部',DATABASE());
INSERT into dept (dname,db_source) VALUES('人事部',DATABASE());
INSERT into dept (dname,db_source) VALUES('财务部',DATABASE());
INSERT into dept (dname,db_source) VALUES('市场部',DATABASE());
INSERT into dept (dname,db_source) VALUES('运维部',DATABASE());

服务提供者集群化

本小节我们将服务提供者springcloud-provider-dept-8001进行集群化。

注意:

  • 服务提供者集群化需要服务的spring-application-name一致!

springcloud-provider-8001

修改application.yaml

server:
  port: 8001

mybatis:
  type-aliases-package: com.langjialing.springcloud.pojo
  config-location: classpath:mybatis/mybatis-config.xml
  mapper-locations: classpath:mybatis/mapper/*.xml

spring:
  application:
    name: springcloud-provider-dept
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/db01?useUnicode=true&characterEncoding=utf-8
    username: root
    password:

# Eureka的配置,服务注册在哪里
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
  instance:
    instance-id: springcloud-provider-dept-8001

# info配置
info:
  app.name: langjialing-springcloud
  url.name: https://潇雅.com

重启模块

重启springcloud-provider-dept-8001模块!

springcloud-provider-8002

创建模块

编辑pom.xml

导入如下依赖:

<dependencies>
        <!-- 需要拿到实体类,因此需要配置api Module。这个类是我们刚才自己写的Module! -->
        <dependency>
            <groupId>com.langjialing</groupId>
            <artifactId>springcloud-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-test</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-jetty</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>

        <!-- 此依赖用于完善监控信息 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
</dependencies>

编辑application.yaml

server:
  port: 8002

mybatis:
  type-aliases-package: com.langjialing.springcloud.pojo
  config-location: classpath:mybatis/mybatis-config.xml
  mapper-locations: classpath:mybatis/mapper/*.xml

spring:
  application:
    name: springcloud-provider-dept
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/db02?useUnicode=true&characterEncoding=utf-8
    username: root
    password:

# Eureka的配置,服务注册在哪里
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
  instance:
    instance-id: springcloud-provider-dept-8002

# info配置
info:
  app.name: langjialing-springcloud
  url.name: https://潇雅.com

编辑Mybatis文件

springcloud-provider-dept-8001Mybatis文件夹全部复制过来即可:

编辑业务代码

springcloud-provider-dept-8001com文件夹全部复制过来,并修改主启动类为对应的名称:

启动模块

启动springcloud-provider-dept-8002模块!

springcloud-provider-8003

创建模块

编辑pom.xml

导入如下依赖:

<dependencies>
        <!-- 需要拿到实体类,因此需要配置api Module。这个类是我们刚才自己写的Module! -->
        <dependency>
            <groupId>com.langjialing</groupId>
            <artifactId>springcloud-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-test</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-jetty</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>

        <!-- 此依赖用于完善监控信息 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
</dependencies>

编辑application.yaml

server:
  port: 8003

mybatis:
  type-aliases-package: com.langjialing.springcloud.pojo
  config-location: classpath:mybatis/mybatis-config.xml
  mapper-locations: classpath:mybatis/mapper/*.xml

spring:
  application:
    name: springcloud-provider-dept
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/db03?useUnicode=true&characterEncoding=utf-8
    username: root
    password:

# Eureka的配置,服务注册在哪里
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
  instance:
    instance-id: springcloud-provider-dept-8003

# info配置
info:
  app.name: langjialing-springcloud
  url.name: https://潇雅.com

编辑Mybatis文件

springcloud-provider-dept-8001Mybatis文件夹全部复制过来即可:

编辑业务代码

springcloud-provider-dept-8001com文件夹全部复制过来,并修改主启动类为对应的名称:

启动模块

启动springcloud-provider-dept-8003模块!

测试功能

Eureka注册中心

访问Eureka集群http://eureka7001.com:7001/http://eureka7002.com:7002/http://eureka7003.com:7003/的任意一个地址都可以看到springcloud-provider-dept集群:

服务请求

多次请求接口,可以看到请求被分别转发到了不同的服务模块。

Ribbon默认的负载均衡规则为轮询规则。

总结

至此,我们实现了服务提供者的集群化以及通过Ribbon来实现简单的轮询负载均衡。我们也可以通过Ribbon来配置不同的负载均衡模式,也可以自定义不同的负载均衡实现。

接下来我们将要介绍feign的负载均衡实现。

捐赠页面示例