原文链接:bbs.huaweicloud.com/blogs/42074…
Java Chassis 的早期版别依靠于 Service Center,供给了许多差异化的竞争力:
- 接口等级转发。 通过注册中心办理微服务的每个版别的元数据,特别是契约数据。 结合契约数据,能够完成版别等级的路由能力。 比方一个微服务存在 v1 和 v2 两个版别, 其间 v1 版别存在接口 op1, op2, v2 版别存在接口 op1, op2, op3, 在灰度场景, Java Chassis能够主动将 op3 的拜访转发到 v2 版别,将 op1, op2 的拜访在 v1, v2版别做负载均衡。
- 根据 version-rule 的实例选择。 客户端能够装备 version-rule, 比方 last, 2.0 等。 这样客户端能够依据实际情况,挑选实例的版别。
Java Chassis过度依靠 Service Center, 为产品的开展带来了一些瓶颈。 Java Chassis的生态推行依靠于 Service Center的生态推行, 不利于Java Chassis被更多用户运用。 随着云的开展, 越来越多的客户也希望一套代码,能够在不同的云环境运转,有些云产商未供给Service Center运转环境,那么用户选择Java Chassis 就会存在顾忌。
根据上述原因, Java Chassis简化了注册发现的依靠,界说了简单简单完成的接口,并根据Nacos
供给了完成,未来还会供给zookeeper
等完成。 Java Chassis 采用了一系列新的规划模式, 确保了在下降注册中心功能依靠的前提下,不下降运用自身的可靠性。
接口等级转发的代替方案
依靠于 Service Center, Java Chassis供给了接口等级转发。 Java Chassis 3 首要做的一个改变是删除了关于接口等级转发的支撑。 这样关于注册中心的依靠复杂度至少能够下降 70%。 然而灰度场景仍然对许多事务比较重要, Java Chassis 3运用灰度发布处理这个问题。 运用灰度发布的优点是不必依靠注册中心供给版别元数据办理能力,只需要每个实例具备版别号等简单元数据信息。
servicecomb:
# enable router for edge service
router:
type: router
routeRule:
business: |
- precedence: 2
match:
apiPath:
prefix: "/business/v2"
route:
- weight: 100
tags:
version: 2.0.0
- precedence: 1
match:
apiPath:
prefix: "/business/v1/dec"
route:
- weight: 50
tags:
version: 1.1.0
- weight: 50
tags:
version: 2.0.0
注册发现接口及其完成
Java Chassis 3 只需要运用Discovery
接口就能够供给新的注册发现支撑。 Java Chassis会调用findServiceInstances
查询实例,假如后续实例发生改变,注册中心完成通过InstanceChangedListener
通知 Java Chassis.
/**
* This is the core service discovery interface. <br/>
*/
public interface Discovery<D extends DiscoveryInstance> extends SPIEnabled, SPIOrder, LifeCycle {
interface InstanceChangedListener<D extends DiscoveryInstance> {
/**
* Called by Discovery Implementations when instance list changed.
* @param registryName Name of the calling discovery implementation
* @param application Microservice application
* @param serviceName Microservice name
* @param updatedInstances The latest updated instances.
*/
void onInstanceChanged(String registryName, String application, String serviceName, List<D> updatedInstances);
}
String name();
/**
* If this implementation enabled for this microservice.
*/
boolean enabled(String application, String serviceName);
/**
* Find all instances.
*
* Life Cycle:This method is called anytime after <code>run</code>.
*
* @param application application
* @param serviceName microservice name
* @return all instances match the criteria.
*/
List<D> findServiceInstances(String application, String serviceName);
/**
* Discovery can call InstanceChangedListener when instance get changed.
*/
void setInstanceChangedListener(InstanceChangedListener<D> instanceChangedListener);
}
Java Chassis 3 通过Registration
来办理注册, 注册过程分为init
、run
、destroy
简单的生命周期, 能够在init
准备注册的数据,run
执行注册,destroy
则在注册失利或者体系中止的时分执行。
/**
* This is the core service registration interface. <br/>
*/
public interface Registration<R extends RegistrationInstance> extends SPIEnabled, SPIOrder, LifeCycle {
String name();
/**
* get MicroserviceInstance </br>
*
* Life Cycle:This method is called anytime after <code>run</code>.
*/
R getMicroserviceInstance();
/**
* update MicroserviceInstance status </br>
*
* Life Cycle:This method is called anytime after <code>run</code>.
*/
boolean updateMicroserviceInstanceStatus(MicroserviceInstanceStatus status);
/**
* adding schemas to Microservice </br>
*
* Life Cycle:This method is called after <code>init</code> and before <code>run</code>.
*/
void addSchema(String schemaId, String content);
/**
* adding endpoints to MicroserviceInstance </br>
*
* Life Cycle:This method is called after <code>init</code> and before <code>run</code>.
*/
void addEndpoint(String endpoint);
/**
* adding property to MicroserviceInstance </br>
*
* Life Cycle:This method is called after <code>init</code> and before <code>run</code>.
*/
void addProperty(String key, String value);
}
注册发现的组合
Java Chassis 3能够独立完成多个Discovery
和Registration
, 达到向多个注册中心注册和从多个注册中心发现实例的作用。 每个实例依据实例ID仅有来标识。 假如实例ID相同, 会被认为是同一个实例, 假如不同, 则会认为是不同的实例。 在Java Chassis 3技能解密:注册中心分区隔离
中聊到了, Java Chassis 要求每次实例注册(新的进程), 生成仅有的实例ID, 以处理注册分区隔离带来的实例假下线问题。Discovery
和Registration
都包含了 Java Chassis 界说的根底信息。
/**
* Standard information used for microservice instance registration and discovery.
*/
public interface MicroserviceInstance {
/**
* Environment(Required): Used for logic separation of microservice instance. Only
* microservice instance with same environment can discovery each other.
*/
String getEnvironment();
/**
* Application(Required): Used for logic separation of microservice instance. Only
* microservice instance with same application can discovery each other.
*/
String getApplication();
/**
* Service Name(Required): Unique identifier for microservice.
*/
String getServiceName();
/**
* Service Name Alias(Optional): Unique identifier for microservice.
* This alias is used by registry implementation to support rename
* of a microservice, e.g. old consumers use old service name can
* find a renamed microservice service.
*/
String getAlias();
/**
* Service Version(Required): version of this microservice.
*/
String getVersion();
/**
* Data center info(Optional).
*/
DataCenterInfo getDataCenterInfo();
/**
* Service Description(Optional)
*/
String getDescription();
/**
* Service Properties(Optional)
*/
Map<String, String> getProperties();
/**
* Service Schemas(Optional): Open API information.
*/
Map<String, String> getSchemas();
/**
* Service endpoints(Optional).
*/
List<String> getEndpoints();
/**
* Microservice instance id(Required). This id can be generated when microservice instance is starting
* or assigned by registry implementation.
*
* When microservice instance is restarted, this id should be changed.
*/
String getInstanceId();
/**
* Microservice service id(Optional). This is used for service center, other implementations may not
* support service id.
*/
default String getServiceId() {
return "";
}
}
在完成注册发现的时分,需要确保该接口界说的根底信息能够注册到注册中心,查询实例的时分,能够获取到这些信息。
客户故事:不把鸡蛋放到同一个篮子里边,是技能选型里边很重要的考量。处理方案的开放性和可代替性、云服务的可代替性,是许多客户都关注的问题。关于一个开源的技能结构,Java Chassis早期的版别虽然规划上也支撑不同的注册中心扩展,但是完成难度很高,不自觉的把客户运用其他注册中心替换 service center的要求变得不可行。供给更加简化的注册发现完成,虽然减少了少数有有竞争力的功能特性,但是极大下降了客户选型的顾忌。