
https://github.com/meituan-dianping
美团内部 Java 微服务架构 OCTO
OCTO-NS由sdk、SGAgent、NSC、Scanner和ZooKeeper组成,使用OCTO-Portal管理端实现可视化服务营运操作,例如更改服务提供者状态、调整权重。服务提供者启动后,通信框架主动发起注册操作,上报服务描述信息接入OCTO-NS。接下来分模块对OCTO-NS进行介绍。
服务治理代理SGAgent
服务注册/发现:这是命名服务的基本功能,注册是提供者上报服务描述信息;发现是消费者根据AppKey获取对应服务描述信息。分为增量和通用两种方式,通用方式是指添加Provider的服务描述信息到对应AppKey下面,为服务列表增加新的成员;增量方式是指一个包含多种ServiceName接口类型的AppKey,通过在注册中心建立ServiceName和AppKey的双向映射,可实现ServiceName粒度的服务注册/发现功能。
服务分组:根据分组信息,SGAgent调整服务节点权重,定制化流量负载。用户可根据需求自定义分组规则,服务分组需要进行事先配置,启动后方能生效。不同分组规则根据优先级排序,优先级高者生效。执行服务分组规则时,对于服务列表中匹配失败的节点进行降权处理,流量极低概率进入降权后的节点(未来管理页面将提供可选按钮,决定降权还是删除规则外服务节点)。目前支持的服务分组策略如下:
a.自定义路由分组:在服务端配置该策略后,可定向指定上游打入下游规则范围内的服务节点
b.同机房优先分组:开启后,服务列表中与调用方非同机房的服务节点被降权
c.同中心优先分组:开启后,服务列表中与调用方非同中心的服务节点被降权
d.同城市路由分组:开启后,服务列表中与调用方非同城的服务节点被降权
标签隔离:依据服务节点中标识的不同标签,实现灵活的流量和链路隔离。服务注册时在服务描述信息中携带标签信息,服务发现时过滤服务列表中持有标签的服务提供者。例如:用以隔离测试的泳道标签,用以单元化部署和灰度链路的单元化标签。
缓存服务NSC
缓存注册到OCTO-NS的服务描述信息,一方面提供批量服务数据缓存与预处理功能,提升服务发现性能;另一方面增强服务治理链路的容灾能力,本地SGAgent不可用的场景下该模块通过HTTP形式提供远程哨兵服务列表。
服务健康Scanner
健康检查模块负责实时检查注册中心的服务提供者健康状况,一旦发现服务提供者不可用就将其置为未启动状态,及时摘除流量;当服务提供者恢复正常时,Scanner会及时将服务提供者的状态置为正常状态,恢复流量。服务整个生命周期内,OCTO-NS利用Scanner实现自动化的流量摘除和恢复,无需业务手动介入。为了提高检查的准确性,Scanner支持OCTO自定义的心跳协议来进行应用层检查,OCTO体系内的通信框架默认支持,无需额外配置。

主要功能
目前提供的功能有服务节点管理,包括服务节点展现,节点启用禁用、节点权重调整、删除节点等。
项目结构
前端部分
后端部分
- 标准Spring Boot工程
项目配置启动
-
提供前后端独立部署方式,前端启动端口8081,访问后端8080端口获取数据,前端支持热加载。
-
运行环境: 建议JDK 1.8及以上,建议Node版本>=10.7.0
-
运行前端 octo-portal-frontend
-
首先在octo-portal-frontend/config/index.js 配置后端ip和端口,然后执行以下命令
cd octo-portal-frontend npm install npm run dev
- 运行后端 octo-portal-server
- 首先在src/main/resources/application.yaml中配置注册中心地址,然后执行以下命令
cd octo-portal-server mvn clean package -Dmvn.test.skip=true cd target java -jar octo-portal-server-0.0.1-SNAPSHOT.jar

/*
* Copyright 2018 Meituan Dianping. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.meituan.octo.portal.controller;
import com.meituan.octo.portal.model.ProviderDesc;
import com.meituan.octo.portal.model.param.ProviderInfoParam;
import com.meituan.octo.portal.model.param.ProviderStatusParam;
import com.meituan.octo.portal.model.param.ProviderWeightParam;
import com.meituan.octo.portal.service.ProviderService;
import com.meituan.octo.portal.util.JsonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/provider")
public class ProviderController {
@Autowired
ProviderService providerService;
/**
* 获取服务下所有节点信息
*/
@RequestMapping(value = "/info", method = RequestMethod.GET)
public String getProviders(@RequestParam(value = "env") int env,
@RequestParam(value = "serviceName") String serviceName) {
List<ProviderDesc> providerDescList = providerService.getProviders(env, serviceName);
return JsonUtil.createSuccess(providerDescList);
}
/**
* 调整权重
*/
@RequestMapping(value = "/weight", method = RequestMethod.PUT)
public String updateProviderWeight(@RequestBody ProviderWeightParam providerWeightParam) {
int env = providerWeightParam.getEnv();
String serviceName = providerWeightParam.getServiceName();
String ip = providerWeightParam.getIp();
int port = providerWeightParam.getPort();
double fweight = providerWeightParam.getWeight();
return providerService.updateProviderWeight(env, serviceName, ip, port, fweight);
}
/**
* 启用禁用状态调整
*/
@RequestMapping(value = "/status", method = RequestMethod.PUT)
public String updateProviderStatus(@RequestBody ProviderStatusParam provierStatusParam) {
int env = provierStatusParam.getEnv();
String serviceName = provierStatusParam.getServiceName();
String ip = provierStatusParam.getIp();
int port = provierStatusParam.getPort();
int newStatus = provierStatusParam.getStatus();
return providerService.updateProviderStatus(env, serviceName, ip, port, newStatus);
}
/**
* 删除节点
*/
@RequestMapping(value = "/info", method = RequestMethod.POST)
public String deleteProvider(@RequestBody ProviderInfoParam providerInfoParam) {
int env = providerInfoParam.getEnv();
String serviceName = providerInfoParam.getServiceName();
String ip = providerInfoParam.getIp();
int port = providerInfoParam.getPort();
return providerService.deleteProvider(env, serviceName, ip, port);
}
}
OCTO https://tech.meituan.com/tags/octo.html 综合介绍
美团大规模微服务通信框架及治理体系OCTO核心组件开源
https://tech.meituan.com/2019/08/08/large-scale-microservice-communication-framework.html
OCTO 2.0:美团基于Service Mesh的服务治理系统详解
https://tech.meituan.com/2021/03/08/octo-2.0-service-mesh.html
美团下一代服务治理系统 OCTO 2.0 的探索与实践
https://tech.meituan.com/2019/12/12/meituan-octo.html
复杂环境下落地Service Mesh的挑战与实践
https://tech.meituan.com/2020/12/03/service-mesh-in-meituan.html
美团弹性伸缩系统的技术演进与落地实践
https://tech.meituan.com/2021/04/01/hulk-kubernetes-docker-octo.html
美团OCTO万亿级数据中心计算引擎技术解析
https://tech.meituan.com/2020/04/23/octo-watt.html
美团命名服务的挑战与演进
https://tech.meituan.com/2020/05/14/octo-mns-2.0.html



更详细的看美团的介绍 https://tech.meituan.com/tags/octo.html
美团 AI 的 GitHub 账号 https://github.com/Meituan-AutoML

328

被折叠的 条评论
为什么被折叠?



