在高速发展的时候,公司规模越来越大,老师人数越来越多,这时候公司不能铺太多人去做运营与服务,必须提高每个人效,这就需要技术驱动。因此掌门教育转变成一家技术驱动型的公司,如果被迫成为一家靠资金驱动的公司就活不下去了。-- 张翼(掌门教育创始人兼CEO)
Eureka 介绍
Zookeeper 介绍
Consul 介绍
上述三个注册中心比较
def registry(ip):
fo = open("service_name.txt", "r")
str = fo.read()
service_name_list = str.split(";")
service_name = service_name_list[random.randint(0,len(service_name_list) - 1)]
fo.close()
client = nacos.NacosClient(nacos_host, namespace='')
print(client.add_naming_instance(service_name,ip,333,"default",1.0,{'preserved.ip.delete.timeout':86400000},True,True))
while True:
print(client.send_heartbeat(service_name,ip,333,"default",1.0,"{}"))
time.sleep(5)
Server集群 | 环境 | 压测时长 | 服务数 | 实例数 | CPU占用 | 内存占用 |
3*1C4G | UAT | 1h | 1499个 | 12715个 | 40% | 50% |
压测结果图
1、Nacos Server 接口测试
描述 | 请求类型 | 请求路径 | 必填参数 | 返回 |
注册实例 | POST | /nacos/v1/ns/instance | ip / port / serviceName | ok |
注销实例 | DELETE | /nacos/v1/ns/instance | ip / port / serviceName | ok |
修改实例 | PUT | /nacos/v1/ns/instance | ip / port / serviceName | ok |
发送心跳 | PUT | /nacos/v1/ns/instance/beat | beat / serviceName | ok |
更新实例健康状态 | PUT | /nacos/v1/ns/health/instance/list | ip / port / serviceName / healthy | ok |
查询实例列表 | GET | /nacos/v1/ns/instance/list | serviceName | JSON串 |
查询实例详情 | GET | /nacos/v1/ns/instance | ip / port / serviceName | JSON串 |
交叉注册
压力测试
请求大于100万次,查看 Sync Server 会不会受到影响,结果 ErrorRequest = 0,同步服务数和实例数没有变化。
有无损调用
自动创建同步
减少 Sync Server
增加 Sync Server
重启 Sync Server
增加 Sync Server 个数,重启 Sync Server ,各节点同步数重新计算且均衡。
Nacos Client 界面重点测试集群管理,服务列表和权限控制。
Nacos Server 重启后,集群管理界面正常展示3台集群节点 IP 。
服务注册 Nacos Server 后,服务列表新增注册上去的服务名和实例个数,而且可查看详情。
服务上下线操作,健康状态和元数据等展示正常。
编辑,删除等操作只有具备 Admin 权限的人员才可操作。
全链路测试路径:API网关 -> 服务A(两个实例) -> 服务B(两个实例)
类名 | 微服务 | 服务端口 | 版本 | 区域 |
SolarServiceA1.java | A1 | 3001 | 1.0 | dev |
SolarServiceA2.java | A2 | 3002 | 1.1 | qa |
SolarServiceB1.java | B1 | 4001 | 1.0 | qa |
SolarServiceB2.java | B2 | 4002 | 1.1 | dev |
SolarZuul.java | Zuul | 5002 | 1.0 | 无 |
@RunWith(SpringRunner.class)
@SpringBootTest(classes = { TestApplication.class, MyTestConfiguration.class }, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class MyTest {
@Autowired
private MyTestCases myTestCases;
private static long startTime;
@BeforeClass
public static void beforeTest() {
startTime = System.currentTimeMillis();
}
@AfterClass
public static void afterTest() {
LOG.info("* Finished automation test in {} seconds", (System.currentTimeMillis() - startTime) / 1000);
}
@Test
public void testNoGray() throws Exception {
myTestCases.testNoGray(gatewayTestUrl);
myTestCases.testNoGray(zuulTestUrl);
}
@Test
public void testVersionStrategyGray() throws Exception {
myTestCases.testVersionStrategyGray1(gatewayGroup, gatewayServiceId, gatewayTestUrl);
myTestCases.testVersionStrategyGray1(zuulGroup, zuulServiceId, zuulTestUrl);
}
}
@Configuration
public class MyTestConfiguration {
@Bean
public MyTestCases myTestCases() {
return new MyTestCases();
}
}
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface DTest {
}
public class MyTestCases {
@Autowired
private TestRestTemplate testRestTemplate;
@DTest
public void testNoGray(String testUrl) {
int noRepeatCount = 0;
List<String> resultList = new ArrayList<String>();
for (int i = 0; i < 4; i++) {
String result = testRestTemplate.getForEntity(testUrl, String.class).getBody();
LOG.info("Result{} : {}", i + 1, result);
if (!resultList.contains(result)) {
noRepeatCount++;
}
resultList.add(result);
}
Assert.assertEquals(noRepeatCount, 4);
}
}
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface DTestConfig {
// 组名
String group();
// 服务名
String serviceId();
// 组名-服务名组合键值的前缀
String prefix() default StringUtils.EMPTY;
// 组名-服务名组合键值的后缀
String suffix() default StringUtils.EMPTY;
// 执行配置的文件路径。测试用例运行前,会把该文件里的内容推送到远程配置中心或者服务
String executePath();
// 重置配置的文件路径。测试用例运行后,会把该文件里的内容推送到远程配置中心或者服务。该文件内容是最初的默认配置
// 如果该注解属性为空,则直接删除从配置中心删除组名-服务名组合键值
String resetPath() default StringUtils.EMPTY;
}
public class MyTestCases {
@Autowired
private TestRestTemplate testRestTemplate;
@DTestConfig(group = "#group", serviceId = "#serviceId", executePath = "gray-strategy-version.xml", resetPath = "gray-default.xml")
public void testVersionStrategyGray(String group, String serviceId, String testUrl) {
for (int i = 0; i < 4; i++) {
String result = testRestTemplate.getForEntity(testUrl, String.class).getBody();
LOG.info("Result{} : {}", i + 1, result);
int index = result.indexOf("[V=1.0]");
int lastIndex = result.lastIndexOf("[V=1.0]");
Assert.assertNotEquals(index, -1);
Assert.assertNotEquals(lastIndex, -1);
Assert.assertNotEquals(index, lastIndex);
}
}
}
<rule>
</rule>
灰度蓝绿生效的配置文件 gray-strategy-version.xml
<rule>
<strategy>
<version>1.0</version>
</strategy>
</rule>
基于 Nacos Client 的自动化测试报告样例
---------- Run automation testcase :: testStrategyCustomizationGray() ----------
Header : [a:"1", b:"2"]
Result1 : zuul -> solar-service-a[192.168.0.107:3002][V=1.1][R=qa][G=solar-group] -> solar-service-b[192.168.0.107:4002][V=1.1][R=dev][G=solar-group]
Result2 : zuul -> solar-service-a[192.168.0.107:3002][V=1.1][R=qa][G=solar-group] -> solar-service-b[192.168.0.107:4002][V=1.1][R=dev][G=solar-group]
Result3 : zuul -> solar-service-a[192.168.0.107:3002][V=1.1][R=qa][G=solar-group] -> solar-service-b[192.168.0.107:4002][V=1.1][R=dev][G=solar-group]
Result4 : zuul -> solar-service-a[192.168.0.107:3002][V=1.1][R=qa][G=solar-group] -> solar-service-b[192.168.0.107:4002][V=1.1][R=dev][G=solar-group]
* Passed
---------- Run automation testcase :: testVersionRuleGray() ----------
Result1 : zuul -> solar-service-a[192.168.0.107:3002][V=1.1][R=qa][G=solar-group] -> solar-service-b[192.168.0.107:4002][V=1.1][R=dev][G=solar-group]
Result2 : zuul -> solar-service-a[192.168.0.107:3001][V=1.0][R=dev][G=solar-group] -> solar-service-b[192.168.0.107:4001][V=1.0][R=qa][G=solar-group]
Result3 : zuul -> solar-service-a[192.168.0.107:3002][V=1.1][R=qa][G=solar-group] -> solar-service-b[192.168.0.107:4002][V=1.1][R=dev][G=solar-group]
Result4 : zuul -> solar-service-a[192.168.0.107:3001][V=1.0][R=dev][G=solar-group] -> solar-service-b[192.168.0.107:4001][V=1.0][R=qa][G=solar-group]
* Passed
作者信息:
吴毅挺,掌门技术副总裁,负责技术中台和少儿技术团队。曾就职于百度、eBay 、携程,曾任携程高级研发总监,负责从零打造携程私有云、容器云、桌面云和 PaaS 平台。
任浩军,掌门基础架构部负责人。曾就职于平安银行、万达、惠普,曾负责平安银行平台架构部 PaaS 平台 Halo 基础服务框架研发。10 多年开源经历,Github ID:@HaojunRen,Nepxion 开源社区创始人,Nacos Group Member,Spring Cloud Alibaba & Nacos & Sentinel & OpenTracing Committer。
参与 Nacos 落地的基础架构部成员,包括: