CSE服务治理实践:负载均衡

作者:高校俱乐部日期:2025/11/22

1 概述

1.1 背景介绍

微服务引擎CSE,是用于微服务应用的云中间件,支持华为云贡献到Apache社区的注册配置中心Servicecomb引擎和开源增强的注册配置中心Nacos引擎。用户可结合其他云服务,快速构建云原生微服务体系,实现微服务应用的快速开发和高可用运维。

1.2 适用对象

  • 企业
  • 个人开发者
  • 高校学生

1.3 案例时间

本案例总时长预计30分钟。

1.4 案例流程

说明: ① 在云主机上搭建CSE本地开发工具; ② 改造E-Commerce-one代码,并启动E-Commerce-one服务,注册到CSE; ③ 改造E-Commerce-two代码,并启动E-Commerce-two服务,注册到CSE; ④ 改造E-Commerce-three代码,并启动E-Commerce-three服务,注册到CSE; ⑤ 改造E-Commerce-consumer代码,并启动E-Commerce-consumer服务,注册到CSE; ⑥ 修改consumer配置切换负载均衡模式。

1.5 资源总览

本案例预计花费总计0元。 |资源名称 |规格| 单价(元)| 时长(h)| |-|-|-|-| |CSE本地开发工具包| ServiceComb引擎2.x,单个微服务数量100,微服务版本数量10000 |0| 0.5| |开发者空间-云主机| 免费版 |0 |0.5|

2 改造项目代码并注册到CSE平台

2.1 下载CSE本地开发工具包并启动服务

参考“云主机CSE环境搭建和服务接入”文档完成本地CSE环境的搭建和启动,在云主机的CodeArts IDE上运行自己的项目,确认项目成功注册到本地CSE。 参考“微服务体验-使用配置中心”文档完成了配置中心相关设置。 为了保证案例数据的准确性,检查CSE平台的配置中心数据是否清空,如果还存在上个案例的变量,需要清除。

2.2 改造项目代码

由于要实现负载均衡的测试效果,所以需要创建多个微服务,包含三个provider服务和一个consumer服务。 首先修改bootstrap.yml文件,完整的文件内容如下:

1spring:
2  application:
3    name: E-Commerce
4
5  cloud:
6    servicecomb:
7      # 注册发现相关配置
8      discovery:     
9        appName: basic-application
10
11        serviceName: ${spring.application.name}
12
13        address: ${PAAS_CSE_SC_ENDPOINT:http://127.0.0.1:30100}
14
15        healthCheckInterval: 10
16
17        pollInterval: 15000
18
19        waitTimeForShutDownInMillis: 15000
20      config:
21
22        serverAddr: ${PAAS_CSE_CC_ENDPOINT:http://127.0.0.1:30110}
23        serverType: kie
24
25        kie:
26          customLabel: ${spring.application.name}
27          customLabelValue: ${INSTANCE_TAG:default}
28
29        fileSource: governance.yaml,application.yaml
30
31

然后修改E-Commerce的pom文件,除了按照2.1步骤引入依赖包以外,还要修改 标签中的项目名,从“E-Commerce”改成“E-Commerce-one”。 完整的pom.xml文件内容如下:

1<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3  <modelVersion>4.0.0</modelVersion>
4  <parent>
5    <groupId>org.springframework.boot</groupId>
6    <artifactId>spring-boot-starter-parent</artifactId>
7    <version>2.6.7</version>
8    <relativePath/>
9  </parent>
10
11  <groupId>org.example</groupId>
12  <artifactId>E-Commerce-one</artifactId>
13  <version>1.0-SNAPSHOT</version>
14  <packaging>jar</packaging>
15
16  <name>E-Commerce-Java</name>
17  <url>http://maven.apache.org</url>
18
19  <properties>
20    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
21  </properties>
22
23  <dependencies>
24    <dependency>
25      <groupId>com.huaweicloud</groupId>
26      <artifactId>spring-cloud-starter-huawei-service-engine</artifactId>
27      <version>1.11.9-2021.0.x</version>
28      <exclusions>
29        <exclusion>
30          <groupId>com.huaweicloud</groupId>
31            <artifactId>spring-cloud-starter-huawei-swagger</artifactId>
32        </exclusion>
33      </exclusions>
34    </dependency>
35    <dependency>
36      <groupId>org.springframework.boot</groupId>
37      <artifactId>spring-boot-starter-web</artifactId>
38    </dependency>
39    <!-- JWT -->
40    <dependency>
41      <groupId>com.auth0</groupId>
42      <artifactId>java-jwt</artifactId>
43      <version>4.4.0</version>
44    </dependency>
45    <!--redis-->
46    <dependency>
47      <groupId>org.springframework.boot</groupId>
48      <artifactId>spring-boot-starter-data-redis</artifactId>
49    </dependency>
50    <!--MyBatis-->
51    <dependency>
52      <groupId>org.mybatis.spring.boot</groupId>
53      <artifactId>mybatis-spring-boot-starter</artifactId>
54      <version>2.2.0</version>
55    </dependency>
56    <dependency>
57      <groupId>mysql</groupId>
58      <artifactId>mysql-connector-java</artifactId>
59      <version>8.0.32</version>
60    </dependency>
61    <!--GaussDB连接驱动-->
62    <!--<dependency>
63      <groupId>com.huawei.opengauss.jdbc</groupId>
64      <artifactId>opengaussjdbc</artifactId>
65      <version>2.0.5</version>
66      <scope>runtime</scope>
67    </dependency>-->
68    <!-- commons-codec依赖 -->
69    <dependency>
70      <groupId>org.apache.commons</groupId>
71      <artifactId>commons-lang3</artifactId>
72      <version>3.3.2</version>
73    </dependency>
74    <dependency>
75      <groupId>commons-codec</groupId>
76      <artifactId>commons-codec</artifactId>
77      <version>1.3</version>
78    </dependency>
79    <dependency>
80      <groupId>javax.validation</groupId>
81      <artifactId>validation-api</artifactId>
82      <version>2.0.1.Final</version>
83    </dependency>
84    <!--Gson 依赖-->
85    <dependency>
86      <groupId>com.google.code.gson</groupId>
87      <artifactId>gson</artifactId>
88      <version>2.8.9</version>
89    </dependency>
90    <!-- lombok -->
91    <dependency>
92      <groupId>org.projectlombok</groupId>
93      <artifactId>lombok</artifactId>
94    </dependency>
95  </dependencies>
96  <build>
97    <plugins>
98      <plugin>
99        <groupId>org.springframework.boot</groupId>
100        <artifactId>spring-boot-maven-plugin</artifactId>
101        <version>2.2.6.RELEASE</version>
102        <configuration>
103          <mainClass>org.example.CommerceApplication</mainClass>
104        </configuration>
105        <executions>
106          <execution>
107            <goals>
108              <goal>repackage</goal>
109            </goals>
110          </execution>
111        </executions>
112      </plugin>
113    </plugins>
114  </build>
115</project>
116

然后找到./src/main/resources目录下的application.yml文件,将服务端口改为8881 在项目代码中找到./src/main/java/org/example/controller目录,打开CommodityController.java文件,将“price”属性的默认值设置为1: 复制三份E-Commerce项目代码,文件夹名称分别命名为E-Commerce-one, E-Commerce-two,E-Commerce-three,E-Commerce-consumer。 按照上面的步骤修改E-Commerce-two和E-Commerce-three,E-Commerce-two的pom文件的项目名改为E-Commerce-two,application.yml文件中端口改为8882,CommodityController文件中price属性默认值改为2;E-Commerce-three的pom文件的项目名改为E-Commerce-three,application.yml文件中端口改为8883,CommodityController文件中price属性默认值改为3。 接下来修改E-Commerce-consumer项目,首先修改pom文件,项目名改为E-Commerce-consumer,application.yml文件中端口改为8090,然后修改同目录下的bootstrap.yml文件: 完整的内容如下:

1spring:
2  application:
3    name: E-Commerce-consumer
4
5  cloud:
6    servicecomb:
7      # 注册发现相关配置
8      discovery:     
9        appName: basic-application
10
11        serviceName: ${spring.application.name}
12
13        address: ${PAAS_CSE_SC_ENDPOINT:http://127.0.0.1:30100}
14
15        healthCheckInterval: 10
16
17        pollInterval: 15000
18
19        waitTimeForShutDownInMillis: 15000
20      config:
21
22        serverAddr: ${PAAS_CSE_CC_ENDPOINT:http://127.0.0.1:30110}
23        serverType: kie
24
25        kie:
26          customLabel: ${spring.application.name}
27          customLabelValue: ${INSTANCE_TAG:default}
28
29        fileSource: governance.yaml,application.yaml
30      loadbalance:
31        AllOperation: |
32        rule: RoundRobin
33

修改E-Commerce-consumer项目的WebConfig文件,内容如下:

1package org.example.config;
2
3import org.example.interceptor.LoginInterceptor;
4import org.springframework.beans.factory.annotation.Autowired;
5import org.springframework.context.annotation.Bean;
6import org.springframework.context.annotation.Configuration;
7import org.springframework.web.client.RestTemplate;
8import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
9import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
10import org.springframework.cloud.client.loadbalancer.LoadBalanced;
11
12@Configuration
13public class WebConfig implements WebMvcConfigurer {
14
15    @Autowired
16    private LoginInterceptor loginInterceptor;
17
18    @Override
19    public void addInterceptors(InterceptorRegistry registry) {
20        //放行登录接口和注册接口
21        registry.addInterceptor(loginInterceptor)
22                .excludePathPatterns("/api/auth/login","/api/auth/register","/api/commodity/*");
23    }
24
25    @Bean
26    @LoadBalanced
27    public RestTemplate restTemplate()
28    {
29        return new RestTemplate();
30    }
31}
32
33

最后修改E-Commerce-consumer项目的CommodityController文件,内容如下:

1package org.example.controller;
2
3import ch.qos.logback.core.util.InvocationGate;
4import org.example.Entity.Commodity;
5import org.example.Entity.Result;
6import org.example.service.CommodityService;
7import org.example.utils.GsonUtil;
8import org.example.utils.JwtUtil;
9import org.springframework.beans.factory.annotation.Autowired;
10import org.springframework.beans.factory.annotation.Value;
11import org.springframework.cloud.context.config.annotation.RefreshScope;
12import org.springframework.validation.annotation.Validated;
13import org.springframework.web.bind.annotation.*;
14import org.springframework.web.client.RestTemplate;
15
16import java.util.List;
17import java.util.Map;
18
19/**
20 * 商品API
21 */
22@Validated
23@RestController
24@RequestMapping("/api/commodity")
25@RefreshScope
26public class CommodityController {
27
28    @Autowired
29    private CommodityService commodityService;
30
31    @Autowired
32    private RestTemplate restTemplate;
33
34    @Value("${test.price:3}")
35    private float price;
36
37    @GetMapping("/list")
38    public Result<List> list(@RequestBody String paramStr){
39        Map<String, Object> paramMap = GsonUtil.jsonToMap(paramStr);
40        //1.分页查询商品列表
41        List<Commodity> list = commodityService.list((String) paramMap.get("keyword"), (Integer) paramMap.get("page_number"), (Integer) paramMap.get("page_size"));
42
43        //2.返回结果
44        return Result.success(list);
45    }
46
47
48    public Result<Commodity> info(@PathVariable("id")Integer id){
49        Commodity commodity = commodityService.findCommodityById(id);
50        float oldprice = commodity.getPrice();
51        commodity.setPrice(price*oldprice);
52        return Result.success(commodity);
53    }
54
55    @GetMapping("/{id}")
56    public Result getBalance(@PathVariable("id")Integer id) {
57        return restTemplate.getForObject("http://E-Commerce/api/commodity/"+id, Result.class);
58  }
59
60}
61

2.3 启动测试微服务

改造好代码,进入四个项目的主目录,执行如下命令将示例代码打成jar包:

1mvn clean package
2

如果提示找不到mvn命令,就需要先安装maven工具,执行如下命令安装maven:

1sudo apt install -y maven
2

进入目录E-Commerce-one/target/,右键点击空白处,在弹出的菜单中选择“在终端打开”,在打开的命令行执行如下命令启动服务,注意不要关闭命令行窗口。

1java -jar E-Commerce-one-1.0-SNAPSHOT.jar
2

进入目录E-Commerce-two/target/,右键点击空白处,在弹出的菜单中选择“在终端打开”,在打开的命令行执行如下命令启动服务,注意不要关闭命令行窗口。

1java -jar E-Commerce-two-1.0-SNAPSHOT.jar
2

进入目录E-Commerce-three/target/,右键点击空白处,在弹出的菜单中选择“在终端打开”,在打开的命令行执行如下命令启动服务,注意不要关闭命令行窗口。

1java -jar E-Commerce-three-1.0-SNAPSHOT.jar
2

进入目录E-Commerce-consumer /target/,右键点击空白处,在弹出的菜单中选择“在终端打开”,在打开的命令行执行如下命令启动服务,注意不要关闭命令行窗口。

1java -jar E-Commerce-consumer-1.0-SNAPSHOT.jar
2

2.4 测试负载均衡轮询模式

上面步骤执行完成后,四个微服务已经启动,在浏览器输入如下地址调用接口: http://localhost:8090/api/commodity/1 注意商品价格的数据,继续调用接口会获得如下信息:
price会有规律的从3.5到7,再到10.5循环出现,也就是商品价格的1到3倍,证明接口循环调用E-Commerce-one、E-Commerce-two、E-Commerce-three三个微服务,这种模式就是轮询模式。

2.5 修改配置文件测试随机模式

进入E-Commerce-consumer 项目的/src/main/resources目录,找到配置文件bootstrap.yml,将下图所示的“RoundRobin”修改为“Random”并保存文件。
关闭2.3步骤中启动E-Commerce-consumer服务的命令行窗口,停止服务,然后回到E-Commerce-consumer项目根目录,右键点击空白处,在弹出的菜单中选择“在终端打开”,在命令行中输入如下命令重新打包E-Commerce-consumer服务jar包:

1mvn clean package
2

打好包后,执行如下命令启动consumer服务,注意不要关闭窗口。

1cd target
2java -jar E-Commerce-consumer-1.0-SNAPSHOT.jar
3

服务启动完成后,在浏览器继续输入如下地址调用接口: http://localhost:8090/api/commodity/1 price会无规律的从3.5到7,再到10.5随机出现,也就是商品价格的1到3倍,证明接口随机调用E-Commerce-one、E-Commerce-two、E-Commerce-three三个微服务,这种模式就是随机模式。

2.6 总结

本案例复制了几份项目代码模拟多个微服务场景,使用consumer服务,通过 RestTemplate 调用几个微服务的接口,通过服务名而不是硬编码的IP地址和端口来调用服务。 负载均衡作用在客户端,是高并发、高可用系统必不可少的关键组件,目标是尽力将网络流量平均分发到多个服务器上,以提高系统整体的响应速度和可用性。


CSE服务治理实践:负载均衡》 是转载文章,点击查看原文


相关推荐


【codex】使用 PLANS.md 进行长时间问题解决
是魔丸啊2025/11/20

转载 Codex 和 gpt-5-codex 模型能够用于实现需要大量时间进行研究、设计和开发的复杂任务。本文介绍的方法是引导模型实现这些任务并促使其成功完成项目的一种有效方式。 这些计划既是详尽的设计文档,也是"动态文档"。作为 Codex 的使用者,您可以借助这些文档来审核 Codex 在启动漫长开发流程前所采取的实施方法。下文包含的 PLANS.md 与让 Codex 能够通过单次提示连续工作超过七小时的文档版本非常相似。 我们通过首先更新 AGENTS.md 来说明何时使用 PLANS.


基于C++的游戏引擎开发
普通网友2025/11/19

1、非修改序列算法 这些算法不会改变它们所操作的容器中的元素。 1.1 find 和 find_if find(begin, end, value):查找第一个等于 value 的元素,返回迭代器(未找到返回 end)。find_if(begin, end, predicate):查找第一个满足谓词的元素。find_end(begin, end, sub_begin, sub_end):查找子序列最后一次出现的位置。 vector<int> nums = {1, 3, 5, 7, 9};


Python 的内置函数 vars
IMPYLH2025/11/17

Python 内建函数列表 > Python 的内置函数 vars Python 的内置函数 vars() 是一个非常有用的工具函数,主要用于返回对象的 __dict__ 属性。它可以应用于模块、类、实例以及其他具有 __dict__ 属性的对象。以下是关于 vars() 函数的详细说明: 基本用法 不带参数调用: 当 vars() 不带参数调用时,它等同于 locals() 函数,返回当前局部作用域的符号表(通常是当前函数的局部变量)。 def example(): x = 1


Python 的内置函数 reversed
IMPYLH2025/11/16

Python 内建函数列表 > Python 的内置函数 reversed Python 的内置函数 reversed() 是一个用于序列反转的高效工具函数,它返回一个反向迭代器对象。以下是关于该函数的详细说明: 基本用法 语法:reversed(seq)参数:seq 可以是任何实现了 __reversed__() 方法的对象,或者支持序列协议(__len__() 和 __getitem__() 方法)的对象返回值:返回一个反向迭代器对象 支持的数据类型 列表:reversed([1,


Python 的内置函数 min
IMPYLH2025/11/15

Python 内建函数列表 > Python 的内置函数 min Python 的内置函数 min() 是一个非常有用的工具函数,用于返回给定参数中的最小值。这个函数可以接受两种形式的参数: 多个单独的参数 min(a, b, c, ...) 它会返回这些参数中的最小值。 一个可迭代对象(如列表、元组、集合等) min(iterable, *[, key, default]) 它会遍历可迭代对象,并返回其中的最小值。 参数说明: iterable:必须是一个可迭代对象(如列表、元


12 节课解锁 AI Agents,让AI替你打工(一): 简介
AI大模型2025/11/14

本文较长,建议点赞收藏。更多AI大模型应用开发学习视频及资料,在智泊AI。 本系列教程主要是为了探索 AI Agent 的设计原理与真实世界应用 随着大语言模型(LLMs)的出现,人工智能取得了巨大飞跃。这些强大的系统彻底改变了自然语言处理,但当它们与智能体(即自主推理、规划和行动的能力)相结合时,其真正潜力才得以释放。这就是大语言模型智能体发挥作用的地方,它代表了我们与人工智能交互和利用方式的范式转变。 图片来源:letta 本文旨在全面概述 AI Agent,深入探讨其特征、组件和类


Lua 的 Coroutine 模块
hubenchang05152025/11/13

#Lua 的 Coroutine 模块 请查看 Lua 标准库模块列表 了解更多相关 API。 函数说明coroutine.create创建协程对象coroutine.close 关闭协程对象coroutine.resume恢复协程coroutine.yield让出协程coroutine.wrap创建协程对象,返回一个恢复函数coroutine.isyieldable检查协程能否让出coroutine.running获取正在运行的协程对象coroutine.status获取协程状态 Lua


Node.js 开发环境搭建全攻略(2025版)
Java私教2025/11/11

本文将详细介绍如何在本地搭建一个高效、可维护的 Node.js 开发环境,适用于 Windows、macOS 与 Linux。无论你是后端新手还是资深全栈工程师,都能通过本文快速构建一个标准化的 Node.js 开发环境。 一、什么是 Node.js? Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时,它让开发者可以在服务器端运行 JavaScript。 它以 事件驱动、非阻塞 I/O 的特性著称,非常适合构建高性能的 Web 服务和微服务架构。 二、安


类比前端知识来学习Java的Spring Boot实现MySql的全栈CRUD功能——搭配Svelte+Vite
水冗水孚2025/11/9

前言 本文梳理了后端的相关操作流程环节 使用Svelte+Vite(前端)搭配Spring Boot(后端) 实现了一个增删改查全栈项目 有助于前端更好理解后端java的分层思想,数据流转控制 和Svelte尝鲜学习了解 完整前后端代码在github:github.com/shuirongshu… 大道至简,一些知识点是相通的比如——python里面也有闭包这个概念 所谓编程即:学习规则语法、理解规则语法、合理运用规则语法、从而自定义规则... Java、Spring、Spring Bo


Bash 的 if 条件语句
hubenchang05152025/11/7

#Bash 的 if 条件语句 Bash 的 if 条件语句的语法为: if 条件命令 then 命令 ... elif 条件命令 then 命令 ... else 命令 ... fi 其中,条件命令返回成功(0)时为真(true),返回失败(非 0)时为假(false)。 如果省略(部分)换行,则需要使用分号(;)区分: if 条件命令; then 命令; 命令; elif 条件命令; then 命令; 命令; else 命令; 命令; fi

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2025 聚合阅读