Cloud-Eureka服务治理-Ribbon负载均衡

构建Cloud父工程

父工程只做依赖版本管理 不引入依赖

pom.xml

复制代码
 <packaging>pom</packaging>


    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.9.RELEASE</version>
        <relativePath/>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR10</spring-cloud.version>
        <mysql.version>5.1.47</mysql.version>
        <mybatis.version>2.1.1</mybatis.version>
        <junit.version>4.12</junit.version>
        <log4j.version>1.2.17</log4j.version>
        <lombok.version>1.16.18</lombok.version>

    </properties>

    <dependencyManagement>
        <dependencies>
            <!-- springCloud -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- mysql驱动 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <!--mybatis-->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis.version}</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
            </dependency>
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>${log4j.version}</version>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
                <optional>true</optional>
            </dependency>
        </dependencies>

    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

构建用户模块

CREATE TABLE `tb_user` (

`id` bigint NOT NULL AUTO_INCREMENT,

`username` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '收件人',

`address` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '地址',

PRIMARY KEY (`id`) USING BTREE,

UNIQUE KEY `username` (`username`) USING BTREE

) ENGINE=InnoDB AUTO_INCREMENT=109 DEFAULT CHARSET=utf8mb3 ROW_FORMAT=COMPACT;

INSERT INTO `tb_user`(`id`, `username`, `address`) VALUES (1, '柳岩', '湖南省衡阳市');

INSERT INTO `tb_user`(`id`, `username`, `address`) VALUES (2, '文二狗', '陕西省西安市');

INSERT INTO `tb_user`(`id`, `username`, `address`) VALUES (3, '华沉鱼', '湖北省十堰市');

INSERT INTO `tb_user`(`id`, `username`, `address`) VALUES (4, '张必沉', '天津市');

INSERT INTO `tb_user`(`id`, `username`, `address`) VALUES (5, '郑爽爽', '辽宁省沈阳市大东区');

INSERT INTO `tb_user`(`id`, `username`, `address`) VALUES (6, '范兵兵', '山东省青岛市');

pom.xml

复制代码
 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
    </dependencies>
    <build>
        <finalName>app</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

application.yml

复制代码
server:
  port: 8081
spring:
  application:
    name: user-service
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/cloud-user?useSSL=false&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=GMT%2B8&useCursorFetch=true
    username: root
    password: 123456
  #redis:
    #port: 6379
    #database: 0
      #password: 1111111111111
      #ssl: false
      ###################################################
      ##redis 集群环境配置
      #cluster:
      #  nodes: 127.0.0.1:7001,127.0.0.1:7002,127.0.0.1:7003
      #  commandTimeout: 5000
mybatis:
  type-aliases-package: com.example.userservice.pojo
  configuration:
    map-underscore-to-camel-case: true
logging:
  level:
    com.example.userservice.mapper: debug

pojo

复制代码
@Data
public class User {
    private Long id;
    private String username;
    private String address;
}

mapper

复制代码
public interface UserMapper {
    
    @Select("select * from tb_user where id = #{id}")
    User findById(@Param("id") Long id);
}

service

复制代码
public interface UserService {
    User queryById(Long id);
}

impl

复制代码
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    public User queryById(Long id) {
        return userMapper.findById(id);
    }
}

controller

复制代码
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {

    @Autowired
    private UserService userService;

    @Value("${server.port}")
    private String serverPort;

    @GetMapping("/serverport")
    public String serverport(){
        return serverPort;
    }


    @GetMapping("/{id}")
    public User queryById(@PathVariable("id") Long id) {
        return userService.queryById(id);
    }
}

这样你可以开多个

构建订单模块

CREATE TABLE `tb_order` (

`id` bigint NOT NULL AUTO_INCREMENT COMMENT '订单id',

`user_id` bigint NOT NULL COMMENT '用户id',

`name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '商品名称',

`price` bigint NOT NULL COMMENT '商品价格',

`num` int DEFAULT '0' COMMENT '商品数量',

PRIMARY KEY (`id`) USING BTREE,

UNIQUE KEY `username` (`name`) USING BTREE

) ENGINE=InnoDB AUTO_INCREMENT=109 DEFAULT CHARSET=utf8mb3 ROW_FORMAT=COMPACT;

INSERT INTO `tb_order` VALUES (101, 1, 'Apple 苹果 iPhone 12 ', 699900, 1);

INSERT INTO `tb_order` VALUES (102, 2, '雅迪 yadea 新国标电动车', 209900, 1);

INSERT INTO `tb_order` VALUES (103, 3, '骆驼(CAMEL)休闲运动鞋女', 43900, 1);

INSERT INTO `tb_order` VALUES (104, 4, '小米10 双模5G 骁龙865', 359900, 1);

INSERT INTO `tb_order` VALUES (105, 5, 'OPPO Reno3 Pro 双模5G 视频双防抖', 299900, 1);

INSERT INTO `tb_order` VALUES (106, 6, '美的(Midea) 新能效 冷静星II ', 544900, 1);

INSERT INTO `tb_order` VALUES (107, 2, '西昊/SIHOO 人体工学电脑椅子', 79900, 1);

INSERT INTO `tb_order` VALUES (108, 3, '梵班(FAMDBANN)休闲男鞋', 31900, 1);

pom.xml

java 复制代码
 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
 <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
    <build>
        <finalName>orderserver</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

pojo

复制代码
@Data
public class Order {
    private Long id;
    private Long price;
    private String name;
    private Integer num;
    private Long userId;
    private User user;
}

@Data
public class User {
    private Long id;
    private String username;
    private String address;
}

mapper

复制代码
public interface OrderMapper {

    @Select("select * from tb_order where id = #{id}")
    Order findById(Long id);
}

service

复制代码
public interface OrderService {
    Order queryOrderById(Long orderId);
}

impl

复制代码
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderMapper orderMapper;


    @Override
    public Order queryOrderById(Long orderId) {
        return orderMapper.findById(orderId);
    }
}

controller

复制代码
@RestController
@RequestMapping("/order")
public class OrderController {


    @Autowired
    private OrderService orderService;

    @GetMapping("{orderId}")
    public Order queryOrderByUserId(@PathVariable("orderId") Long orderId) {
        // 根据id查询订单并返回
        return orderService.queryOrderById(orderId);
    }
}

合并公共代码

像pojo可以放在common-api里

构建基础公用模块

使用RestTemplate进行服务间调用

服务调用出现的问题

通过硬编码的方式调用,那么当服务多了又该如何应对

搭建单机Eureka服务

服务既可以是生产者,也可是是消费者 也可以同时扮演生产者和消费者两个角色

Eureka分服务端和客户端

我们要注册进去的OrderServer和UserServer都是客户端

所有注册到Eureka的服务每30秒都会给注册中心发送心跳检测,证明我活着

java 复制代码
server:
  port: 7001
spring:
  application:
    name: eureka-server
eureka:
  instance:
    hostname: eurekaserver  # eureka服务端的实例名称  集群的时候配置
  client:
    # 表示不向注册中心注册自己  集群必须为true
    register-with-eureka: true
    # 表示自己就是注册中心,职责是维护服务实例,并不需要去检索服务  单
    fetch-registry: true
    service-url:
      # 设置与eureka server交互的地址查询服务和注册服务都需要依赖这个地址  ${}是上面定义的
      defaultZone: http://127.0.0.1:${server.port}/eureka/

服务注册(将order-server和user-server注册到Eureka服务)

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>

</dependency>

两个客户端都添加依赖

两个application.yml

通过IDEA设置启动多个生产者

这样也行

通过Ribbon实现负载均衡

为了看清楚调用的是哪个端口服务

修改Ribbon负载均衡方式

有两种方式 一种是添加配置类 另外一种是application.yml配置

添加配置Bean的方式 注意这种方式针对的是所有 如果非要用这种方式去配置单一服务方法也是有的 自行扩展

如果想用这种方式配置某个服务的负载均衡 自己试试 我没试过

application.yml配置方式

Ribbon 提供了多种负载均衡策略,可以根据不同的场景和需求来选择。下面介绍几种常用的策略及其配置方式:

1. RoundRobinRule(轮询策略)

默认策略,按顺序逐一调用服务器。如果服务器达到列表末尾,调用将从头开始。

配置方式

application.yml中配置:

复制代码

yamlCopy code

your-service-name: ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule

2. RandomRule(随机策略)

随机选择一个服务器进行调用。

配置方式

application.yml中配置:

复制代码

yamlCopy code

your-service-name: ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

3. RetryRule(重试策略)

在一个配置的重试时间内,当选择的服务器不成功时,使用子规则(默认为轮询)重新选择一个可用的服务器。

配置方式

application.yml中配置:

复制代码

yamlCopy code

your-service-name: ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RetryRule

4. WeightedResponseTimeRule(响应时间加权策略)

根据服务器的响应时间分配权重。响应时间越快的服务器被选中的可能性越高。随着时间的推移,权重会动态调整。

配置方式

application.yml中配置:

复制代码

yamlCopy code

your-service-name: ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule

5. BestAvailableRule(最少并发请求策略)

选择并发请求最小的服务器。适用于负载比较重的操作。

配置方式

application.yml中配置:

复制代码

yamlCopy code

your-service-name: ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.BestAvailableRule

6. AvailabilityFilteringRule(可用性过滤策略)

过滤掉一直连接失败的被标记为 circuit tripped 的服务器,以及并发连接数超过阈值的服务器,然后选择一个并发量最小的服务器。

配置方式

application.yml中配置:

复制代码

yamlCopy code

your-service-name: ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.AvailabilityFilteringRule

7. ZoneAvoidanceRule(区域敏感策略)

复合判断server所在区域的性能和server的可用性选择服务器。

配置方式

application.yml中配置:

复制代码

yamlCopy code

your-service-name: ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.ZoneAvoidanceRule

配置注意事项

  • your-service-name应该替换为你的服务名称。
  • 在使用特定策略时,确保已经了解其工作原理及适用场景,以免影响服务的稳定性和性能。
  • 随着Spring Cloud的版本更新,一些配置方式可能会有所变化,建议查看最新的官方文档进行配置。

配置饥饿加载

单个服务的配置

相关推荐
聪明的笨猪猪41 分钟前
Java JVM “内存(1)”面试清单(含超通俗生活案例与深度理解)
java·经验分享·笔记·面试
_dindong1 小时前
Linux网络编程:Socket编程TCP
linux·服务器·网络·笔记·学习·tcp/ip
金士顿1 小时前
ethercat网络拓扑详细学习
学习
知识分享小能手1 小时前
uni-app 入门学习教程,从入门到精通,uni-app组件 —— 知识点详解与实战案例(4)
前端·javascript·学习·微信小程序·小程序·前端框架·uni-app
wahkim1 小时前
Flutter 学习资源及视频
学习
摇滚侠2 小时前
Spring Boot 3零基础教程,WEB 开发 Thymeleaf 属性优先级 行内写法 变量选择 笔记42
java·spring boot·笔记
摇滚侠2 小时前
Spring Boot 3零基础教程,WEB 开发 Thymeleaf 总结 热部署 常用配置 笔记44
java·spring boot·笔记
没有bug.的程序员2 小时前
金融支付分布式架构实战:从理论到生产级实现
java·分布式·微服务·金融·架构·分布式调度系统
小白要努力sgy2 小时前
待学习--中间件
学习·中间件
rechol2 小时前
汇编与底层编程笔记
汇编·arm开发·笔记