加入Capa,共建社区:https://github.com/capa-cloud/sigs
欢迎来到 Capa 文档库!
加入Capa,共建社区:https://github.com/capa-cloud/sigs
欢迎来到 Capa 文档库!
This is a placeholder page that shows you how to use this template site.
让代码实现"一次编写,随处运行"。
借助Capa体系,使你的Java应用在改动量较小的情况下,拥有跨云、混合云运行的能力。
Capa项目基于Mecha架构的设计理念,使用 富SDK模式 提供Multi-Runtime的标准API。
您可以简单的将Capa项目理解为 Dapr / Layotto 等Sidecar模式项目的SDK实现版本。
欲要理解Mecha架构的设计思路,请阅读以下文章:
MOSN子项目Layotto:开启服务网格+应用运行时新篇章
基于Mecha架构理念的Multi-Runtime,以Sidecar的方式提供标准API的功能,看起来似乎是最合理的选择。
那为什么不直接使用Dapr/Layotto等项目,而是选择开发 富SDK模式 的Capa项目呢。
概括:以Dapr为代表的Sidecar架构是未来,但现有的很多企业和系统很难一步到位的升级到Sidecar架构,富SDK架构将会长期的存在下去。
引申:面对庞大的Java系统体系,Capa项目将使用富SDK模型支持Java系统向Mecha架构过渡。在Dapr等项目成熟后,也可以无缝衔接到Sidecar架构。
关于此问题的具体讨论请参考:
Capa API设计follow社区标准,请参考 Dapr / Layotto 等开源项目的API定义。
API定义放置于以下独立仓库中,与Capa项目解绑,希望发展成为社区的API标准定义:
由于目前Dapr API和Dapr项目强绑定,但我们希望这套API能够成为整个社区的标准,所以Capa将API定义放在独立仓库中,并时刻和上游社区标准保持同步。
我们希望后续Dapr能够将其API独立部署出来,与Dapr项目相解耦,成为整个社区的标准。
关于此项的讨论,请查看:
Capa(Java SDK)是面向Java应用实现Mecha架构的SDK解决方案,它目前支持以下领域的特性:
设计思路:标准API + 可拔插可替换的SDK组件 模式
在不同的分布式中间件领域,Capa提供与具体中间件API无关的统一的标准编程API。 所以应用程序在使用Capa编程时不需要依赖任何具体的中间件API,只需要依赖Capa的标准编程API即可。
在部署到不同的目标环境时,Capa将会装载标准API的不同实现类到应用程序中。当调用统一的编程API时,底层运行时会适配到不同的具体中间件SDK实现。
中间件团队需要针对不同目标环境,开发标准API在目标环境下的实现类即可;而应用代码可以拥有"一次编写,随处运行"的开发体验。
Capa module划分主要为以下几个部分:
应用程序编程时只需要依赖sdk即可,并使用SDK模块中定义的统一编程API。
在运行前,会将具体的SPI实现包引入进去,作为统一编程API的具体实现。
For a Maven project, add the following to your pom.xml file:
<project>
...
<dependencies>
...
<!-- Capa's core SDK with all features. -->
<dependency>
<groupId>group.rxcloud</groupId>
<artifactId>capa-sdk</artifactId>
<version>1.0.7.RELEASE</version>
</dependency>
...
</dependencies>
...
</project>
Sample implementation library:
<project>
...
<dependencies>
...
<!-- Capa's core SDK with all features. -->
<dependency>
<groupId>group.rxcloud</groupId>
<artifactId>capa-sdk-spi-demo</artifactId>
<version>1.0.7.RELEASE</version>
</dependency>
...
</dependencies>
...
</project>
Try the following examples to learn more about Capa’s Java SDK:
如果要使用原生的Capa API,您的遗留系统需要面对较大的重构工作量。
为了使迁移做到低成本,我们可以复用目前使用到的中间件API。
通过开发一个适配层项目(提供相同的注解/接口调用方式),将原中间件API的实现更改为Capa API。
如此一来,应用程序只需要更改很少的代码(例如更换注解/接口的路径名)即可迁移到Capa架构。
关于该问题的讨论,请查看:
Java sdk design 调研:能否复用业界已有的事实标准
Capa API adapted to spring annotation.
考虑到异步调用模式,以及非阻塞IO的使用,我们原生提供Reactor的编程模型,您也可以通过其block()方法使用同步调用的功能。
The Java SDK for Capa is built using Project Reactor. It provides an asynchronous API for
Java. When consuming a result is consumed synchronously, as in the examples referenced above, the block() method is
used.
The code below does not make any API call, it simply returns the Mono publisher object. Nothing happens until the application subscribes or blocks on the result:
Mono<String> result=capaRpcClient.invokeMethod(SERVICE_APP_ID,"say","hello",HttpExtension.POST,null,TypeRef.STRING);
To start execution and receive the result object synchronously, use block(). The code below shows how to execute the
call and consume an empty response:
Mono<String> result=capaRpcClient.invokeMethod(SERVICE_APP_ID,"say","hello",HttpExtension.POST,null,TypeRef.STRING);
String response=result.block();
Most exceptions thrown from the SDK are instances of CapaException. CapaException extends from RuntimeException,
making it compatible with Project Reactor.
感谢您对Capa的支持!
CapaConfigurationClient提供的配置能力,需要实现具体的实现类来适配不同的平台(通过继承CapaConfigStoreSpi抽象类),如示例DemoCapaConfigStore
通过spi机制实现对具体实现类的加载。具体配置过程为:在项目resources路径下,新增capa-component-configuration.properties文件。
在文件中新增属性key:“group.rxcloud.capa.component.configstore.CapaConfigStore”,value:“实现类的全路径”;新增属性key:“CONFIGURATION_COMPONENT_STORE_NAME”,value:“config store name"示例如下:
//capa-component-configuration.properties文件
group.rxcloud.capa.component.configstore.CapaConfigStore=group.rxcloud.capa.spi.demo.configstore.DemoCapaConfigStore
CONFIGURATION_COMPONENT_STORE_NAME=DEMO CONFIG
调用相应Configuration API进行应用级配置管理
public final class CapaConfigStoreClientProvider {
private static volatile CapaConfigurationClient client;
public static CapaConfigurationClient getClient() {
if (client == null) {
synchronized (CapaConfigStoreClientProvider.class) {
if (client == null) {
StoreConfig storeConfig = new StoreConfig();
storeConfig.setStoreName(Optional.ofNullable(CapaProperties.COMPONENT_PROPERTIES_SUPPLIER.apply("configuration").getProperty("CONFIGURATION_COMPONENT_STORE_NAME")).orElse("UN_CONFIGURED_STORE_CONFIG_NAME"));
client = new CapaConfigurationClientBuilder(storeConfig).build();
}
}
}
return client;
}
private CapaConfigStoreClientProvider() {
}
}
//拿到单例client
private static final CapaConfigurationClient client = CapaConfigurationClientSingleton.getClient();
//getConfiguration()其中一个重载方法
Mono<List<ConfigurationItem<User>>> configMono = client.getConfiguration(new ConfigurationRequestItem(),TypeRef.get(User.class));
//getConfiguration()另一个重载方法
Mono<List<ConfigurationItem<User>>> configMono = client.getConfiguration("config",
SERVICE_APP_ID,
Lists.newArrayList("test.json"),
metaDataMap,
"group",
"label"
TypeRef.get(User.class));
//阻塞获取配置结果
List<ConfigurationItem<User>> config = configMono.block();
//本地存配置的变量
private SubConfigurationResp<String> cur;
//subscribeConfiguration()其中一个重载方法
Flux<SubConfigurationResp<User>> configFlux = client.subscribeConfiguration(new ConfigurationRequestItem(),TypeRef.get(User.class))
//subscribeConfiguration()另一个重载方法
Flux<SubConfigurationResp<User>> configFlux = client.subscribeConfiguration("config",
SERVICE_APP_ID,
Lists.newArrayList("test.json"),
metaDataMap,
"group",
"label"
TypeRef.get(User.class));
//订阅后续的变更并更新原数据
configFlux.subscribe(resp -> cur.setItems(resp.getItems()));
Mono<Void> configFlux = client.saveConfiguration(new SaveConfigurationRequest());
Mono<Void> configFlux = client.deleteConfiguration(new ConfigurationRequestItem());
ps:以上api存在重载方法,点击此处查询全部api列表
CapaRpcClient capaRpcClient = new CapaRpcClientBuilder().build();
Mono<byte[]> responseMono = capaRpcClient.invokeMethod(SERVICE_APP_ID,
"hello",
"hello",
HttpExtension.POST,
null,
TypeRef.BYTE_ARRAY);
byte[] response = responseMono.block();
感谢您对Capa的支持!
Configuration API的实现类Demo示例
ps:其中配置文件Demo中仅“group.rxcloud.capa.component.configstore.CapaConfigStore”和Configuration相关,其他property可以忽略
由于当前处于高速迭代中,代码和版本都很不稳定,文档可能不是最新版本,接入jar包版本和流程都可能会有较大改动,请查看最后更新时间,若和当前时间超过一周请咨询相关开发询问是否有较大改动!!!
**last updated on 2021/12/06
21/12/06/18:32 updated maven dependency
step1.引入maven依赖
<dependencyManagement>
<dependency>
<groupId>group.rxcloud</groupId>
<artifactId>capa-framework-dependencies</artifactId>
<version>1.0.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependency>
<groupId>group.rxcloud</groupId>
<artifactId>capa-spi-aws-config</artifactId>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
</dependency>
携程用户需要额外引入(目前jar包在携程私服上,仅限携程开发使用)
<dependency>
<groupId>group.rxcloud</groupId>
<artifactId>capa-adaptor-group.rxcloud-qconfig</artifactId>
</dependency>
此外还提供foundation方法包,供使用方获取appId,provider,env,namespace,region使用(该foundation中的其他方法并未测试,请不要使用)
<dependency>
<groupId>group.rxcloud</groupId>
<artifactId>capa-foundation</artifactId>
<version>1.0.4.RELEASE</version>
</dependency>
ps:后续会统一放入capa-framework-dependencies bom中进行管理
step2.代码改动
public final class CapaConfigStoreClientProvider {
private static volatile CapaConfigurationClient client;
public static CapaConfigurationClient getClient() {
if (client == null) {
synchronized (CapaConfigStoreClientProvider.class) {
if (client == null) {
StoreConfig storeConfig = new StoreConfig();
//对应实现的storeName
storeConfig.setStoreName(storeName);
client = new CapaConfigurationClientBuilder(storeConfig).build();
}
}
}
return client;
}
private CapaConfigStoreClientProvider() {
}
}
private static final CapaConfigurationClient client = CapaConfigStoreClientProvider.getClient();
//根据自身填入storeName,appId
Mono<List<ConfigurationItem<User>>> configMono = client.getConfiguration(
storeName,
appId,
Lists.newArrayList("test.json"),
null,
"",
"",
TypeRef.get(User.class));
//阻塞获取配置结果
List<ConfigurationItem<User>> config = configMono.block();
//带超时时间的阻塞,自定义超时时间
List<ConfigurationItem<User>> config = configMono.block(Duration.ofSeconds(30));
subscribe
//本地存配置的变量
private static SubConfigurationResp<User> cur;
static {
//根据自身填入storeName,appId
Flux<SubConfigurationResp<User>> configFlux = client.subscribeConfiguration(
storeName,
appId,
Lists.newArrayList("test.json"),
null,
"",
"",
TypeRef.get(User.class));
//阻塞初始化配置
cur = configFlux.blockFirst();
//或使用带超时时间的阻塞初始化配置,自定义超时时间
cur = configFlux.blockFirst(Duration.ofSeconds(30));
//订阅变更并更新原数据
configFlux.subscribe(resp -> cur.setItems(resp.getItems()));
}
public String getConfig() {
User user = cur.getItems().get(0).getContent();
System.out.println("-----------------------------------age:" + user.getName());
}
使用adaptor包中的@QConfig注解替换QConfig中原来的@QConfig注解:将import qunar.tc.qconfig.client.spring.QConfig;修改为import group.rxcloud.capa.adaptor.group.rxcloud.qconfig.annotation.QConfig;
代码写法
@Service
public class JsonConfigService {
@QConfig("testjson.json")
private Person person;//非监听模式,支持热更新
@QConfig("testjson.json")
private void onChange(Person person) {//监听模式
System.out.println(person);
}
public String getPerson() {
return JSON.toJSONString(person);
}
}
private static final CapaConfigurationClient client = CapaConfigurationClientProvider.getClient();
//从adaptor中CapaConfigStoreClientProvider静态方法中获取storeName(必须)和appid(可选,可以自己从app.properties中读,也可以使用Foundation.app().getAppId() ps:此包为capa-foundation包提供的方法,仅在aws实现下使用)
Mono<List<ConfigurationItem<User>>> configMono = client.getConfiguration(
CapaConfigurationClientProvider.provideStoreName(),
Foundation.app().getAppId(),
Lists.newArrayList("test.json"),
null,
TypeRef.get(User.class));
//阻塞获取配置结果
List<ConfigurationItem<User>> config = configMono.block();
//或带超时时间的阻塞,自定义超时时间
List<ConfigurationItem<User>> config = configMono.block(Duration.ofSeconds(30));
subscribe
//本地存配置的变量
private static SubConfigurationResp<User> cur;
static {
//从adaptor中CapaConfigStoreClientProvider静态方法中获取storeName(必须)和appid(可选,可以自己从app.properties中读,也可以使用Foundation.app().getAppId() ps:此包为capa-foundation包提供的方法,仅在aws实现下使用)
Flux<SubConfigurationResp<User>> configFlux = client.subscribeConfiguration(
CapaConfigurationClientProvider.provideStoreName(),
Foundation.app().getAppId(),
Lists.newArrayList("test.json"),
null,
TypeRef.get(User.class));
//阻塞初始化配置
cur = configFlux.blockFirst();
//或使用带超时时间的阻塞初始化配置,自定义超时时间
cur = configFlux.blockFirst(Duration.ofSeconds(30));
//订阅变更并更新原数据
configFlux.subscribe(resp -> cur.setItems(resp.getItems()));
}
public String getConfig() {
User user = cur.getItems().get(0).getContent();
System.out.println("-----------------------------------age:" + user.getName());
}
@Override
<T> Mono<List<ConfigurationItem<T>>> getConfiguration(String storeName, String appId, List<String> keys, Map<String, String> metadata, TypeRef<T> type);
@Override
<T> Mono<List<ConfigurationItem<T>>> getConfiguration(String storeName, String appId, List<String> keys, Map<String, String> metadata, String group, TypeRef<T> type);
@Override
<T> Mono<List<ConfigurationItem<T>>> getConfiguration(String storeName, String appId, List<String> keys, Map<String, String> metadata, String group, String label, TypeRef<T> type);
@Override
<T> Flux<SubConfigurationResp<T>> subscribeConfiguration(String storeName, String appId, List<String> keys, Map<String, String> metadata, TypeRef<T> type);
@Override
<T> Flux<SubConfigurationResp<T>> subscribeConfiguration(String storeName, String appId, List<String> keys, Map<String, String> metadata, String group, TypeRef<T> type);
@Override
<T> Flux<SubConfigurationResp<T>> subscribeConfiguration(String storeName, String appId, List<String> keys, Map<String, String> metadata, String group, String label, TypeRef<T> type);
@Override
<T> Mono<List<ConfigurationItem<T>>> getConfiguration(ConfigurationRequestItem configurationRequestItem, TypeRef<T> type);
@Override
<T> Flux<SubConfigurationResp<T>> subscribeConfiguration(ConfigurationRequestItem configurationRequestItem, TypeRef<T> type);
@Override
Mono<Void> saveConfiguration(SaveConfigurationRequest saveConfigurationRequest);
@Override
Mono<Void> deleteConfiguration(ConfigurationRequestItem configurationRequestItem);
针对AWS云的设施基础现状下,选型AWS AppConfig为应用级别配置管理组件
继承CapaConfigStoreSpi抽象类,底层通过对appconfig的封装,实现相应的Configuration API
通过SPI机制引入相关实现类。具体流程为:
#capa-component-configuration.properties文件
group.rxcloud.capa.component.configstore.CapaConfigStore=group.rxcloud.capa.spi.aws.config.AwsCapaConfigStore
# configuration component store names
CONFIGURATION_COMPONENT_STORE_NAMES=aws.appconfig
# configstore aws app config env
CONFIG_AWS_APP_CONFIG_ENV=ENV
调用方通过使用Capa统一规范的Configuration API即可完成对应用级别配置的管理需求。
由于当前处于高速迭代中,代码和版本都很不稳定,文档可能不是最新版本,接入jar包版本和流程都可能会有较大改动,请查看最后更新时间,若和当前时间超过一周请咨询相关开发询问是否有较大改动!!!
last updated on 2021/12/06
step1.引入maven依赖
21/12/06/18:32 updated maven dependency
<dependencyManagement>
<dependency>
<groupId>group.rxcloud</groupId>
<artifactId>capa-framework-dependencies</artifactId>
<version>1.0.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependency>
<groupId>group.rxcloud</groupId>
<artifactId>capa-spi-group.rxcloud-qconfig</artifactId>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
</dependency>
<dependency>
<groupId>group.rxcloud</groupId>
<artifactId>capa-adaptor-group.rxcloud-qconfig</artifactId>
</dependency>
step2.相关代码修改
@Service
public class JsonConfigService {
@QConfig("testjson.json")
private Person person;//非监听模式,支持热更新
@QConfig("testjson.json")
private void onChange(Person person) {//监听模式
System.out.println(person);
}
public String getPerson() {
return JSON.toJSONString(person);
}
}
private static final CapaConfigurationClient client = CapaConfigurationClientProvider.getClient();
//从adaptor中CapaConfigStoreClientProvider静态方法中获取storeName(必须)
Mono<List<ConfigurationItem<User>>> configMono = client.getConfiguration(
CapaConfigurationClientProvider.provideStoreName(),
appid,
Lists.newArrayList("test.json"),
null,
TypeRef.get(User.class));
//阻塞获取配置结果
List<ConfigurationItem<User>> config = configMono.block();
//带超时时间的阻塞,自定义超时时间
List<ConfigurationItem<User>> config = configMono.block(Duration.ofSeconds(30));
//本地存配置的变量
private static SubConfigurationResp<User> cur;
static {
//从adaptor中CapaConfigStoreClientProvider静态方法中获取storeName(必须)
Flux<SubConfigurationResp<User>> configFlux = client.subscribeConfiguration(
CapaConfigurationClientProvider.provideStoreName(),
appid,
Lists.newArrayList("test.json"),
null,
TypeRef.get(User.class));
//阻塞初始化配置
cur = configFlux.blockFirst();
//或使用带超时时间的阻塞初始化配置,自定义超时时间
cur = configFlux.blockFirst(Duration.ofSeconds(30));
//订阅变更并更新原数据
configFlux.subscribe(resp -> cur.setItems(resp.getItems()));
}
public String getConfig() {
User user = cur.getItems().get(0).getContent();
System.out.println("-----------------------------------age:" + user.getName());
}
@Override
<T> Mono<List<ConfigurationItem<T>>> getConfiguration(String storeName, String appId, List<String> keys, Map<String, String> metadata, TypeRef<T> type);
@Override
<T> Mono<List<ConfigurationItem<T>>> getConfiguration(String storeName, String appId, List<String> keys, Map<String, String> metadata, String group, TypeRef<T> type);
@Override
<T> Mono<List<ConfigurationItem<T>>> getConfiguration(String storeName, String appId, List<String> keys, Map<String, String> metadata, String group, String label, TypeRef<T> type);
@Override
<T> Flux<SubConfigurationResp<T>> subscribeConfiguration(String storeName, String appId, List<String> keys, Map<String, String> metadata, TypeRef<T> type);
@Override
<T> Flux<SubConfigurationResp<T>> subscribeConfiguration(String storeName, String appId, List<String> keys, Map<String, String> metadata, String group, TypeRef<T> type);
@Override
<T> Flux<SubConfigurationResp<T>> subscribeConfiguration(String storeName, String appId, List<String> keys, Map<String, String> metadata, String group, String label, TypeRef<T> type);
@Override
<T> Mono<List<ConfigurationItem<T>>> getConfiguration(ConfigurationRequestItem configurationRequestItem, TypeRef<T> type);
@Override
<T> Flux<SubConfigurationResp<T>> subscribeConfiguration(ConfigurationRequestItem configurationRequestItem, TypeRef<T> type);
@Override
Mono<Void> saveConfiguration(SaveConfigurationRequest saveConfigurationRequest);
@Override
Mono<Void> deleteConfiguration(ConfigurationRequestItem configurationRequestItem);

ps:Service(appid:123)为举例,表示一个应用id为123的服务,下面直接缩写成ServiceA
针对携程全家桶的设施基础现状下,选型Qconfig为应用级别配置管理组件
继承CapaConfigStoreSpi抽象类,底层通过对Qconfig的封装,实现相应的Configuration API
通过SPI机制引入相关实现类。具体流程为:
#capa-component-configuration.properties文件
group.rxcloud.capa.component.configstore.CapaConfigStore=group.rxcloud.capa.spi.group.rxcloud.configstore.CtripCapaConfigStore
CONFIGURATION_COMPONENT_STORE_NAME=group.rxcloud.qconfig
#暂无配置
调用方通过使用Capa统一规范的Configuration API即可完成对应用级别配置的管理需求。
@Override
<T> Mono<T> invokeMethod(String appId, String methodName, Object data, HttpExtension httpExtension, Map<String, String> metadata, TypeRef<T> type);
@Override
<T> Mono<T> invokeMethod(String appId, String methodName, Object request, HttpExtension httpExtension, Map<String, String> metadata, Class<T> clazz);
@Override
<T> Mono<T> invokeMethod(String appId, String methodName, Object request, HttpExtension httpExtension, TypeRef<T> type);
@Override
<T> Mono<T> invokeMethod(String appId, String methodName, Object request, HttpExtension httpExtension, Class<T> clazz);
@Override
<T> Mono<T> invokeMethod(String appId, String methodName, HttpExtension httpExtension, Map<String, String> metadata, TypeRef<T> type);
@Override
<T> Mono<T> invokeMethod(String appId, String methodName, HttpExtension httpExtension, Map<String, String> metadata, Class<T> clazz);
@Override
Mono<Void> invokeMethod(String appId, String methodName, Object request, HttpExtension httpExtension, Map<String, String> metadata);
@Override
Mono<Void> invokeMethod(String appId, String methodName, Object request, HttpExtension httpExtension);
@Override
Mono<Void> invokeMethod(String appId, String methodName, HttpExtension httpExtension, Map<String, String> metadata);
@Override
Mono<byte[]> invokeMethod(String appId, String methodName, byte[] request, HttpExtension httpExtension, Map<String, String> metadata);
@Override
<T> Mono<T> invokeMethod(InvokeMethodRequest invokeMethodRequest, TypeRef<T> type);
下图为 Capa 的 RPC 在携程的 App Mesh 服务调用逻辑

实现 RpcServiceOptions (实际 RPC 调用需要的参数) 和 CtripSpiOptionsLoader (加载 RpcServiceOptions 的实现类) 接口。
例如 AwsRpcServiceOptions 和 AwsSpiOptionsLoader
继承 CapaSerializeHttpSpi , 实现在携程 Service Mesh 的 RPC 调用。
例如 AwsCapaHttp
构建 capa-component-rpc.properties 文件,添加 group.rxcloud.capa.component.http.CapaHttp 和 group.rxcloud.capa.spi.config.CapaSpiOptionsLoader 对应的类的路径,以支持 SPI 方式加载对应的类。
例如:
group.rxcloud.capa.component.http.CapaHttp=group.rxcloud.capa.spi.group.rxcloud.http.AwsCapaHttp
group.rxcloud.capa.spi.config.CapaSpiOptionsLoader=group.rxcloud.capa.spi.group.rxcloud.config.AwsSpiOptionsLoader
@Override
<T> Mono<T> invokeMethod(String appId, String methodName, Object data, HttpExtension httpExtension, Map<String, String> metadata, TypeRef<T> type);
@Override
<T> Mono<T> invokeMethod(String appId, String methodName, Object request, HttpExtension httpExtension, Map<String, String> metadata, Class<T> clazz);
@Override
<T> Mono<T> invokeMethod(String appId, String methodName, Object request, HttpExtension httpExtension, TypeRef<T> type);
@Override
<T> Mono<T> invokeMethod(String appId, String methodName, Object request, HttpExtension httpExtension, Class<T> clazz);
@Override
<T> Mono<T> invokeMethod(String appId, String methodName, HttpExtension httpExtension, Map<String, String> metadata, TypeRef<T> type);
@Override
<T> Mono<T> invokeMethod(String appId, String methodName, HttpExtension httpExtension, Map<String, String> metadata, Class<T> clazz);
@Override
Mono<Void> invokeMethod(String appId, String methodName, Object request, HttpExtension httpExtension, Map<String, String> metadata);
@Override
Mono<Void> invokeMethod(String appId, String methodName, Object request, HttpExtension httpExtension);
@Override
Mono<Void> invokeMethod(String appId, String methodName, HttpExtension httpExtension, Map<String, String> metadata);
@Override
Mono<byte[]> invokeMethod(String appId, String methodName, byte[] request, HttpExtension httpExtension, Map<String, String> metadata);
@Override
<T> Mono<T> invokeMethod(InvokeMethodRequest invokeMethodRequest, TypeRef<T> type);
下图为 Capa 的 RPC 在携程的 Service Mesh 服务调用逻辑

实现 RpcServiceOptions (实际 RPC 调用需要的参数) 和 CtripSpiOptionsLoader (加载 RpcServiceOptions 的实现类) 接口。
例如 CtripRpcServiceOptions 和 CtripSpiOptionsLoader
继承 CapaSerializeHttpSpi , 实现在携程 Service Mesh 的 RPC 调用。
例如 CtripCapaHttp
构建 capa-component-rpc.properties 文件,添加 group.rxcloud.capa.component.http.CapaHttp 和 group.rxcloud.capa.spi.config.CapaSpiOptionsLoader 对应的类的路径,以支持 SPI 方式加载对应的类。
例如:
group.rxcloud.capa.component.http.CapaHttp=group.rxcloud.capa.spi.group.rxcloud.http.CtripCapaHttp
group.rxcloud.capa.spi.config.CapaSpiOptionsLoader=group.rxcloud.capa.spi.group.rxcloud.config.CtripSpiOptionsLoader
在跨云、混合云的场景下,我们希望应用程序可以使用一套代码,部署到不同的云环境上。在运行时,采用对应云环境提供的云原生实现方案。

定义与具体中间件无关的API层(无强绑定),使应用程序在编程时仅依赖该API层。 如此一来,应用本身便与具体中间件解耦;然后在部署到不同云环境时,将API的不同云的实现层加载到应用进程中。
全面的可观测指标度量规范定义

参考资料:https://segmentfault.com/a/1190000040061004
参考资料:https://www.51cto.com/article/691184.html

参考资料:https://segmentfault.com/a/1190000040061004
命名空间采用分级域名命名方式:
(顶级域名).一级域名.二级域名.三级域名.x.y.z
顶级域名应标识所属云(私有云、公有云)等基础设施。
但目前各云监控指标命名空间本身隔离,故不考虑加入顶级域名。
将云原生技术栈划分为4个领域,一级域名标识了所属的层级。
对应一级域命名空间为:
参考云原生技术栈图示给出的四个层次,使一级域名能够显示出Actuator所属的层级。

携程监控指标的一级域名主要有System、FrameworkName、App等等。
不过其技术栈领域的监控划分主要依赖于:使用不同看板进行呈现,相当于不同的监控平台本身对应于不同的技术栈领域。
应用层的监控主要还是以FrameworkName为主,反映出了携程是以框架为主体,框架就强绑定了该领域的概念(看到Dal就意味着关系型数据库、看到SOA就意味着RPC领域)。
Ops运维和管理领域:
应用层,应在二级域名进行应用类型的划分。
在这里,我们参考携程的应用类型设计,取运行时语言作为划分:
主要基于中间件维度进行定义:
以基础设施作为划分:
基于以上 一级域名(技术栈领域).二级域名(组件领域划分) 的命名空间,我们已经能够体现具体领域。
但每个领域,都可能有多种实现。
例如在中间件领域,携程命名空间做了 中间件-领域 的强绑定。
所以在三级域名的设计上,我们希望体现一些更细节的信息。
但没有必要像一二级域名一样,保持独立的语义。
故使用 小写+下划线 作为三级域名的格式标准。
包含更丰富的语义,但视觉上不像一二级域名一样强烈。
三级域名如果有更多细节需要体现,通过追加的方式进行拓展。
从实用性上来看,可以不使用三级域名,直接基于appId等。
如果要使用,参考携程应用类型定义。
组件领域,可能有多种 中间件实现 / 工具。
所以在三级域名上,我们希望体现 中间件/工具 的概念。
组件领域,中间件领域,都可能有多种编程语言的实现,其SDK内部逻辑不可能完全一致。
所以在三级域名上,我们希望体现 编程语言 的概念。
对于Fxc而言,目前已有(中间件名称_编程语言):
对于Inf而言,目前已有(工具/产品名称):
携程在监控命名上,强体现 框架名称。
中间件领域命名空间
使用 小写+下划线 作为 监控指标 名称的格式标准。
监控指标设计分为:Level0、Level1、Level2层次。
必需监控指标:
拓展监控指标
xx定义为 操作/业务 名称
请求量:
耗时:
成功率:
使用 小写+下划线 作为attributes的格式标准。
通过调用Capa SDK API的方式,管理应用级配置。底层通过SPI的方式注册适配各平台的实现类。
下图为Capa的Configuration服务调用逻辑

Capa Configuration API的设计参考了社区的规范
具体参数含义如下:
| 参数 | 含义 |
|---|---|
| storeName | 存储名称 |
| appId | 同一命名空间内的服务唯一ID |
| keys | 配置key列表 |
| metadata | 发送配置请求的元信息 |
| group | 配置组(Optional) |
| label | 配置标签(Optional) |
| type | 请求响应对象中的泛型对应的具体类型 |
| ConfigurationRequestItem | 请求对象 |
| ConfigurationItem | 获取配置的响应对象 |
| SubConfigurationResp | 订阅配置的响应对象 |
下图为 Capa 的 RPC 服务调用逻辑

Capa的 api 设计参照了社区的规范
具体参数含义如下:
| 参数 | 含义 |
|---|---|
| appId | 同一命名空间内的服务唯一ID |
| methodName | 被调用服务的方法名 |
| request | 要发送调用的服务请求 |
| httpExtension | HTTP请求方式 |
| metadata | 发送请求的元数据(GRPC)或者请求头(HTTP) |
| clazz | 请求响应的类型 |
| type | 请求响应的类型 |
| invokeMethodRequest | 请求对象 |
经过调研,发现AWS在RPC上
通过服务调用,应用程序可以使用 HTTP 这样的标准协议来发现并可靠地与其他应用程序通信。
下图为 Capa 的 RPC 服务调用逻辑

Capa的 api 设计参照了社区的规范
具体参数含义如下:
| 参数 | 含义 |
|---|---|
| appId | 同一命名空间内的服务唯一ID |
| methodName | 被调用服务的方法名 |
| request | 要发送调用的服务请求 |
| httpExtension | HTTP请求方式 |
| metadata | 发送请求的元数据(GRPC)或者请求头(HTTP) |
| clazz | 请求响应的类型 |
| type | 请求响应的类型 |
| invokeMethodRequest | 请求对象 |
This is a placeholder page that shows you how to use this template site.
Think about your project’s features and use cases. Use these to choose your core tasks. Each granular use case (enable x, configure y) should have a corresponding tasks page or tasks page section. Users should be able to quickly refer to your core tasks when they need to find out how to do one specific thing, rather than having to look for the instructions in a bigger tutorial or example. Think of your tasks pages as a cookbook with different procedures your users can combine to create something more substantial.
You can give each task a page, or you can group related tasks together in a page, such as tasks related to a particular feature. As well as grouping related tasks in single pages, you can also group task pages in nested folders with an index page as an overview, as seen in this example site. Or if you have a small docset like the Docsy User Guide with no Tutorials or Concepts pages, consider adding your feature-specific pages at the top level of your docs rather than in a Tasks section.
Each task should give the user
This is a placeholder page. Replace it with your own content.
Text can be bold, italic, or strikethrough. Links should be blue with no underlines (unless hovered over).
There should be whitespace between paragraphs. Vape migas chillwave sriracha poutine try-hard distillery. Tattooed shabby chic small batch, pabst art party heirloom letterpress air plant pop-up. Sustainable chia skateboard art party banjo cardigan normcore affogato vexillologist quinoa meggings man bun master cleanse shoreditch readymade. Yuccie prism four dollar toast tbh cardigan iPhone, tumblr listicle live-edge VHS. Pug lyft normcore hot chicken biodiesel, actually keffiyeh thundercats photo booth pour-over twee fam food truck microdosing banh mi. Vice activated charcoal raclette unicorn live-edge post-ironic. Heirloom vexillologist coloring book, beard deep v letterpress echo park humblebrag tilde.
90’s four loko seitan photo booth gochujang freegan tumeric listicle fam ugh humblebrag. Bespoke leggings gastropub, biodiesel brunch pug fashion axe meh swag art party neutra deep v chia. Enamel pin fanny pack knausgaard tofu, artisan cronut hammock meditation occupy master cleanse chartreuse lumbersexual. Kombucha kogi viral truffaut synth distillery single-origin coffee ugh slow-carb marfa selfies. Pitchfork schlitz semiotics fanny pack, ugh artisan vegan vaporware hexagon. Polaroid fixie post-ironic venmo wolf ramps kale chips.
There should be no margin above this first sentence.
Blockquotes should be a lighter gray with a border along the left side in the secondary color.
There should be no margin below this final sentence.
This is a normal paragraph following a header. Knausgaard kale chips snackwave microdosing cronut copper mug swag synth bitters letterpress glossier craft beer. Mumblecore bushwick authentic gochujang vegan chambray meditation jean shorts irony. Viral farm-to-table kale chips, pork belly palo santo distillery activated charcoal aesthetic jianbing air plant woke lomo VHS organic. Tattooed locavore succulents heirloom, small batch sriracha echo park DIY af. Shaman you probably haven’t heard of them copper mug, crucifix green juice vape single-origin coffee brunch actually. Mustache etsy vexillologist raclette authentic fam. Tousled beard humblebrag asymmetrical. I love turkey, I love my job, I love my friends, I love Chardonnay!
Deae legum paulatimque terra, non vos mutata tacet: dic. Vocant docuique me plumas fila quin afuerunt copia haec o neque.
On big screens, paragraphs and headings should not take up the full container width, but we want tables, code blocks and similar to take the full width.
Scenester tumeric pickled, authentic crucifix post-ironic fam freegan VHS pork belly 8-bit yuccie PBR&B. I love this life we live in.
This is a blockquote following a header. Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.
This is a code block following a header.
Next level leggings before they sold out, PBR&B church-key shaman echo park. Kale chips occupy godard whatever pop-up freegan pork belly selfies. Gastropub Belinda subway tile woke post-ironic seitan. Shabby chic man bun semiotics vape, chia messenger bag plaid cardigan.
| What | Follows |
|---|---|
| A table | A header |
| A table | A header |
| A table | A header |
There’s a horizontal rule above and below this.
Here is an unordered list:
And an ordered list:
And an unordered task list:
And a “mixed” task list:
And a nested list:
Definition lists can be used with Markdown syntax. Definition headers are bold.
Tables should have bold headings and alternating shaded rows.
| Artist | Album | Year |
|---|---|---|
| Michael Jackson | Thriller | 1982 |
| Prince | Purple Rain | 1984 |
| Beastie Boys | License to Ill | 1986 |
If a table is too wide, it should scroll horizontally.
| Artist | Album | Year | Label | Awards | Songs |
|---|---|---|---|---|---|
| Michael Jackson | Thriller | 1982 | Epic Records | Grammy Award for Album of the Year, American Music Award for Favorite Pop/Rock Album, American Music Award for Favorite Soul/R&B Album, Brit Award for Best Selling Album, Grammy Award for Best Engineered Album, Non-Classical | Wanna Be Startin’ Somethin’, Baby Be Mine, The Girl Is Mine, Thriller, Beat It, Billie Jean, Human Nature, P.Y.T. (Pretty Young Thing), The Lady in My Life |
| Prince | Purple Rain | 1984 | Warner Brothers Records | Grammy Award for Best Score Soundtrack for Visual Media, American Music Award for Favorite Pop/Rock Album, American Music Award for Favorite Soul/R&B Album, Brit Award for Best Soundtrack/Cast Recording, Grammy Award for Best Rock Performance by a Duo or Group with Vocal | Let’s Go Crazy, Take Me With U, The Beautiful Ones, Computer Blue, Darling Nikki, When Doves Cry, I Would Die 4 U, Baby I’m a Star, Purple Rain |
| Beastie Boys | License to Ill | 1986 | Mercury Records | noawardsbutthistablecelliswide | Rhymin & Stealin, The New Style, She’s Crafty, Posse in Effect, Slow Ride, Girls, (You Gotta) Fight for Your Right, No Sleep Till Brooklyn, Paul Revere, Hold It Now, Hit It, Brass Monkey, Slow and Low, Time to Get Ill |
Code snippets like var foo = "bar"; can be shown inline.
Also, this should vertically align with thisand this.
Code can also be shown in a block element.
foo := "bar";
bar := "foo";
Code can also use syntax highlighting.
func main() {
input := `var foo = "bar";`
lexer := lexers.Get("javascript")
iterator, _ := lexer.Tokenise(nil, input)
style := styles.Get("github")
formatter := html.New(html.WithLineNumbers())
var buff bytes.Buffer
formatter.Format(&buff, style, iterator)
fmt.Println(buff.String())
}
Long, single-line code blocks should not wrap. They should horizontally scroll if they are too long. This line should be long enough to demonstrate this.
Inline code inside table cells should still be distinguishable.
| Language | Code |
|---|---|
| Javascript | var foo = "bar"; |
| Ruby | foo = "bar"{ |
Small images should be shown at their actual size.
![]()
Large images should always scale down and fit in the content container.
![]()
The photo above of the Spruce Picea abies shoot with foliage buds: Bjørn Erik Pedersen, CC-BY-SA.
Add some sections here to see how the ToC looks like. Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.
Inguina genus: Anaphen post: lingua violente voce suae meus aetate diversi. Orbis unam nec flammaeque status deam Silenum erat et a ferrea. Excitus rigidum ait: vestro et Herculis convicia: nitidae deseruit coniuge Proteaque adiciam eripitur? Sitim noceat signa probat quidem. Sua longis fugatis quidem genae.
Tilde photo booth wayfarers cliche lomo intelligentsia man braid kombucha vaporware farm-to-table mixtape portland. PBR&B pickled cornhole ugh try-hard ethical subway tile. Fixie paleo intelligentsia pabst. Ennui waistcoat vinyl gochujang. Poutine salvia authentic affogato, chambray lumbersexual shabby chic.
Plaid hell of cred microdosing, succulents tilde pour-over. Offal shabby chic 3 wolf moon blue bottle raw denim normcore poutine pork belly.
Stumptown PBR&B keytar plaid street art, forage XOXO pitchfork selvage affogato green juice listicle pickled everyday carry hashtag. Organic sustainable letterpress sartorial scenester intelligentsia swag bushwick. Put a bird on it stumptown neutra locavore. IPhone typewriter messenger bag narwhal. Ennui cold-pressed seitan flannel keytar, single-origin coffee adaptogen occupy yuccie williamsburg chillwave shoreditch forage waistcoat.
This is the final element on the page and there should be no margin below this.
This is a placeholder page. Replace it with your own content.
Text can be bold, italic, or strikethrough. Links should be blue with no underlines (unless hovered over).
There should be whitespace between paragraphs. Vape migas chillwave sriracha poutine try-hard distillery. Tattooed shabby chic small batch, pabst art party heirloom letterpress air plant pop-up. Sustainable chia skateboard art party banjo cardigan normcore affogato vexillologist quinoa meggings man bun master cleanse shoreditch readymade. Yuccie prism four dollar toast tbh cardigan iPhone, tumblr listicle live-edge VHS. Pug lyft normcore hot chicken biodiesel, actually keffiyeh thundercats photo booth pour-over twee fam food truck microdosing banh mi. Vice activated charcoal raclette unicorn live-edge post-ironic. Heirloom vexillologist coloring book, beard deep v letterpress echo park humblebrag tilde.
90’s four loko seitan photo booth gochujang freegan tumeric listicle fam ugh humblebrag. Bespoke leggings gastropub, biodiesel brunch pug fashion axe meh swag art party neutra deep v chia. Enamel pin fanny pack knausgaard tofu, artisan cronut hammock meditation occupy master cleanse chartreuse lumbersexual. Kombucha kogi viral truffaut synth distillery single-origin coffee ugh slow-carb marfa selfies. Pitchfork schlitz semiotics fanny pack, ugh artisan vegan vaporware hexagon. Polaroid fixie post-ironic venmo wolf ramps kale chips.
There should be no margin above this first sentence.
Blockquotes should be a lighter gray with a border along the left side in the secondary color.
There should be no margin below this final sentence.
This is a normal paragraph following a header. Knausgaard kale chips snackwave microdosing cronut copper mug swag synth bitters letterpress glossier craft beer. Mumblecore bushwick authentic gochujang vegan chambray meditation jean shorts irony. Viral farm-to-table kale chips, pork belly palo santo distillery activated charcoal aesthetic jianbing air plant woke lomo VHS organic. Tattooed locavore succulents heirloom, small batch sriracha echo park DIY af. Shaman you probably haven’t heard of them copper mug, crucifix green juice vape single-origin coffee brunch actually. Mustache etsy vexillologist raclette authentic fam. Tousled beard humblebrag asymmetrical. I love turkey, I love my job, I love my friends, I love Chardonnay!
Deae legum paulatimque terra, non vos mutata tacet: dic. Vocant docuique me plumas fila quin afuerunt copia haec o neque.
On big screens, paragraphs and headings should not take up the full container width, but we want tables, code blocks and similar to take the full width.
Scenester tumeric pickled, authentic crucifix post-ironic fam freegan VHS pork belly 8-bit yuccie PBR&B. I love this life we live in.
This is a blockquote following a header. Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.
This is a code block following a header.
Next level leggings before they sold out, PBR&B church-key shaman echo park. Kale chips occupy godard whatever pop-up freegan pork belly selfies. Gastropub Belinda subway tile woke post-ironic seitan. Shabby chic man bun semiotics vape, chia messenger bag plaid cardigan.
| What | Follows |
|---|---|
| A table | A header |
| A table | A header |
| A table | A header |
There’s a horizontal rule above and below this.
Here is an unordered list:
And an ordered list:
And an unordered task list:
And a “mixed” task list:
And a nested list:
Definition lists can be used with Markdown syntax. Definition headers are bold.
Tables should have bold headings and alternating shaded rows.
| Artist | Album | Year |
|---|---|---|
| Michael Jackson | Thriller | 1982 |
| Prince | Purple Rain | 1984 |
| Beastie Boys | License to Ill | 1986 |
If a table is too wide, it should scroll horizontally.
| Artist | Album | Year | Label | Awards | Songs |
|---|---|---|---|---|---|
| Michael Jackson | Thriller | 1982 | Epic Records | Grammy Award for Album of the Year, American Music Award for Favorite Pop/Rock Album, American Music Award for Favorite Soul/R&B Album, Brit Award for Best Selling Album, Grammy Award for Best Engineered Album, Non-Classical | Wanna Be Startin’ Somethin’, Baby Be Mine, The Girl Is Mine, Thriller, Beat It, Billie Jean, Human Nature, P.Y.T. (Pretty Young Thing), The Lady in My Life |
| Prince | Purple Rain | 1984 | Warner Brothers Records | Grammy Award for Best Score Soundtrack for Visual Media, American Music Award for Favorite Pop/Rock Album, American Music Award for Favorite Soul/R&B Album, Brit Award for Best Soundtrack/Cast Recording, Grammy Award for Best Rock Performance by a Duo or Group with Vocal | Let’s Go Crazy, Take Me With U, The Beautiful Ones, Computer Blue, Darling Nikki, When Doves Cry, I Would Die 4 U, Baby I’m a Star, Purple Rain |
| Beastie Boys | License to Ill | 1986 | Mercury Records | noawardsbutthistablecelliswide | Rhymin & Stealin, The New Style, She’s Crafty, Posse in Effect, Slow Ride, Girls, (You Gotta) Fight for Your Right, No Sleep Till Brooklyn, Paul Revere, Hold It Now, Hit It, Brass Monkey, Slow and Low, Time to Get Ill |
Code snippets like var foo = "bar"; can be shown inline.
Also, this should vertically align with thisand this.
Code can also be shown in a block element.
foo := "bar";
bar := "foo";
Code can also use syntax highlighting.
func main() {
input := `var foo = "bar";`
lexer := lexers.Get("javascript")
iterator, _ := lexer.Tokenise(nil, input)
style := styles.Get("github")
formatter := html.New(html.WithLineNumbers())
var buff bytes.Buffer
formatter.Format(&buff, style, iterator)
fmt.Println(buff.String())
}
Long, single-line code blocks should not wrap. They should horizontally scroll if they are too long. This line should be long enough to demonstrate this.
Inline code inside table cells should still be distinguishable.
| Language | Code |
|---|---|
| Javascript | var foo = "bar"; |
| Ruby | foo = "bar"{ |
Small images should be shown at their actual size.
![]()
Large images should always scale down and fit in the content container.
![]()
The photo above of the Spruce Picea abies shoot with foliage buds: Bjørn Erik Pedersen, CC-BY-SA.
Add some sections here to see how the ToC looks like. Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.
Inguina genus: Anaphen post: lingua violente voce suae meus aetate diversi. Orbis unam nec flammaeque status deam Silenum erat et a ferrea. Excitus rigidum ait: vestro et Herculis convicia: nitidae deseruit coniuge Proteaque adiciam eripitur? Sitim noceat signa probat quidem. Sua longis fugatis quidem genae.
Tilde photo booth wayfarers cliche lomo intelligentsia man braid kombucha vaporware farm-to-table mixtape portland. PBR&B pickled cornhole ugh try-hard ethical subway tile. Fixie paleo intelligentsia pabst. Ennui waistcoat vinyl gochujang. Poutine salvia authentic affogato, chambray lumbersexual shabby chic.
Plaid hell of cred microdosing, succulents tilde pour-over. Offal shabby chic 3 wolf moon blue bottle raw denim normcore poutine pork belly.
Stumptown PBR&B keytar plaid street art, forage XOXO pitchfork selvage affogato green juice listicle pickled everyday carry hashtag. Organic sustainable letterpress sartorial scenester intelligentsia swag bushwick. Put a bird on it stumptown neutra locavore. IPhone typewriter messenger bag narwhal. Ennui cold-pressed seitan flannel keytar, single-origin coffee adaptogen occupy yuccie williamsburg chillwave shoreditch forage waistcoat.
This is the final element on the page and there should be no margin below this.
This is a placeholder page. Replace it with your own content.
Text can be bold, italic, or strikethrough. Links should be blue with no underlines (unless hovered over).
There should be whitespace between paragraphs. Vape migas chillwave sriracha poutine try-hard distillery. Tattooed shabby chic small batch, pabst art party heirloom letterpress air plant pop-up. Sustainable chia skateboard art party banjo cardigan normcore affogato vexillologist quinoa meggings man bun master cleanse shoreditch readymade. Yuccie prism four dollar toast tbh cardigan iPhone, tumblr listicle live-edge VHS. Pug lyft normcore hot chicken biodiesel, actually keffiyeh thundercats photo booth pour-over twee fam food truck microdosing banh mi. Vice activated charcoal raclette unicorn live-edge post-ironic. Heirloom vexillologist coloring book, beard deep v letterpress echo park humblebrag tilde.
90’s four loko seitan photo booth gochujang freegan tumeric listicle fam ugh humblebrag. Bespoke leggings gastropub, biodiesel brunch pug fashion axe meh swag art party neutra deep v chia. Enamel pin fanny pack knausgaard tofu, artisan cronut hammock meditation occupy master cleanse chartreuse lumbersexual. Kombucha kogi viral truffaut synth distillery single-origin coffee ugh slow-carb marfa selfies. Pitchfork schlitz semiotics fanny pack, ugh artisan vegan vaporware hexagon. Polaroid fixie post-ironic venmo wolf ramps kale chips.
There should be no margin above this first sentence.
Blockquotes should be a lighter gray with a border along the left side in the secondary color.
There should be no margin below this final sentence.
This is a normal paragraph following a header. Knausgaard kale chips snackwave microdosing cronut copper mug swag synth bitters letterpress glossier craft beer. Mumblecore bushwick authentic gochujang vegan chambray meditation jean shorts irony. Viral farm-to-table kale chips, pork belly palo santo distillery activated charcoal aesthetic jianbing air plant woke lomo VHS organic. Tattooed locavore succulents heirloom, small batch sriracha echo park DIY af. Shaman you probably haven’t heard of them copper mug, crucifix green juice vape single-origin coffee brunch actually. Mustache etsy vexillologist raclette authentic fam. Tousled beard humblebrag asymmetrical. I love turkey, I love my job, I love my friends, I love Chardonnay!
Deae legum paulatimque terra, non vos mutata tacet: dic. Vocant docuique me plumas fila quin afuerunt copia haec o neque.
On big screens, paragraphs and headings should not take up the full container width, but we want tables, code blocks and similar to take the full width.
Scenester tumeric pickled, authentic crucifix post-ironic fam freegan VHS pork belly 8-bit yuccie PBR&B. I love this life we live in.
This is a blockquote following a header. Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.
This is a code block following a header.
Next level leggings before they sold out, PBR&B church-key shaman echo park. Kale chips occupy godard whatever pop-up freegan pork belly selfies. Gastropub Belinda subway tile woke post-ironic seitan. Shabby chic man bun semiotics vape, chia messenger bag plaid cardigan.
| What | Follows |
|---|---|
| A table | A header |
| A table | A header |
| A table | A header |
There’s a horizontal rule above and below this.
Here is an unordered list:
And an ordered list:
And an unordered task list:
And a “mixed” task list:
And a nested list:
Definition lists can be used with Markdown syntax. Definition headers are bold.
Tables should have bold headings and alternating shaded rows.
| Artist | Album | Year |
|---|---|---|
| Michael Jackson | Thriller | 1982 |
| Prince | Purple Rain | 1984 |
| Beastie Boys | License to Ill | 1986 |
If a table is too wide, it should scroll horizontally.
| Artist | Album | Year | Label | Awards | Songs |
|---|---|---|---|---|---|
| Michael Jackson | Thriller | 1982 | Epic Records | Grammy Award for Album of the Year, American Music Award for Favorite Pop/Rock Album, American Music Award for Favorite Soul/R&B Album, Brit Award for Best Selling Album, Grammy Award for Best Engineered Album, Non-Classical | Wanna Be Startin’ Somethin’, Baby Be Mine, The Girl Is Mine, Thriller, Beat It, Billie Jean, Human Nature, P.Y.T. (Pretty Young Thing), The Lady in My Life |
| Prince | Purple Rain | 1984 | Warner Brothers Records | Grammy Award for Best Score Soundtrack for Visual Media, American Music Award for Favorite Pop/Rock Album, American Music Award for Favorite Soul/R&B Album, Brit Award for Best Soundtrack/Cast Recording, Grammy Award for Best Rock Performance by a Duo or Group with Vocal | Let’s Go Crazy, Take Me With U, The Beautiful Ones, Computer Blue, Darling Nikki, When Doves Cry, I Would Die 4 U, Baby I’m a Star, Purple Rain |
| Beastie Boys | License to Ill | 1986 | Mercury Records | noawardsbutthistablecelliswide | Rhymin & Stealin, The New Style, She’s Crafty, Posse in Effect, Slow Ride, Girls, (You Gotta) Fight for Your Right, No Sleep Till Brooklyn, Paul Revere, Hold It Now, Hit It, Brass Monkey, Slow and Low, Time to Get Ill |
Code snippets like var foo = "bar"; can be shown inline.
Also, this should vertically align with thisand this.
Code can also be shown in a block element.
foo := "bar";
bar := "foo";
Code can also use syntax highlighting.
func main() {
input := `var foo = "bar";`
lexer := lexers.Get("javascript")
iterator, _ := lexer.Tokenise(nil, input)
style := styles.Get("github")
formatter := html.New(html.WithLineNumbers())
var buff bytes.Buffer
formatter.Format(&buff, style, iterator)
fmt.Println(buff.String())
}
Long, single-line code blocks should not wrap. They should horizontally scroll if they are too long. This line should be long enough to demonstrate this.
Inline code inside table cells should still be distinguishable.
| Language | Code |
|---|---|
| Javascript | var foo = "bar"; |
| Ruby | foo = "bar"{ |
Small images should be shown at their actual size.
![]()
Large images should always scale down and fit in the content container.
![]()
The photo above of the Spruce Picea abies shoot with foliage buds: Bjørn Erik Pedersen, CC-BY-SA.
Add some sections here to see how the ToC looks like. Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.
Inguina genus: Anaphen post: lingua violente voce suae meus aetate diversi. Orbis unam nec flammaeque status deam Silenum erat et a ferrea. Excitus rigidum ait: vestro et Herculis convicia: nitidae deseruit coniuge Proteaque adiciam eripitur? Sitim noceat signa probat quidem. Sua longis fugatis quidem genae.
Tilde photo booth wayfarers cliche lomo intelligentsia man braid kombucha vaporware farm-to-table mixtape portland. PBR&B pickled cornhole ugh try-hard ethical subway tile. Fixie paleo intelligentsia pabst. Ennui waistcoat vinyl gochujang. Poutine salvia authentic affogato, chambray lumbersexual shabby chic.
Plaid hell of cred microdosing, succulents tilde pour-over. Offal shabby chic 3 wolf moon blue bottle raw denim normcore poutine pork belly.
Stumptown PBR&B keytar plaid street art, forage XOXO pitchfork selvage affogato green juice listicle pickled everyday carry hashtag. Organic sustainable letterpress sartorial scenester intelligentsia swag bushwick. Put a bird on it stumptown neutra locavore. IPhone typewriter messenger bag narwhal. Ennui cold-pressed seitan flannel keytar, single-origin coffee adaptogen occupy yuccie williamsburg chillwave shoreditch forage waistcoat.
This is the final element on the page and there should be no margin below this.
Capa采用SDK模型,相比于Sidecar模型将带来很多问题:
本章主要介绍Capa在SDK实践中,遇到的一些问题以及相关的解决思路。
Java SDK主要使用Maven进行管理,故以下内容主要基于Maven进行实践。
根据Capa设计,接入层面向API层的SDK进行编程,然后在运行时动态调用不同的实现层SDK。
问题:
若包含所有的实现层SDK,则面对依赖冲突的可能性大增。
有的实现层SDK在初始化时执行了操作,若将A云的实现层jar打包到B云的包中,可能有未知的问题出现。
综上,不使用该方案。
基于Maven提供的profile机制,可以将不同云的实现打包到不同的包中,最终生成不同的镜像。
可以避免不同云SDK之间的冲突,以及可以针对性的添加个性化的配置。
具体实现主要有以下思路:
但动态修改 pom 文件本身并不推荐。
maven 官方建议直接指定需要的依赖:
综上,不使用该方案。
面对的问题:
但以上问题,提高了复杂度,但减少了面对未知问题的可能性,更有利于生产的稳定性。
所以使用该种方式。
本文介绍在SDK-Java中的依赖管理实践经验。
因为有了依赖传递,我们就不需要考虑依赖的依赖如何管理了,maven都会把他们加载进来,但是这么多依赖都进来到底用哪个,会不会冲突呢?
maven在解析pom时,会使用依赖调解,具体原则有:
第一原则 路径最近者优先
A -> B -> X(1.0) A -> C -> D -> X(2.0)
X(1.0) 路径长度为2,X(2.0)路径长度3,所以 X(1.0) 会被真正的使用
第二原则 第一声明者优先
A -> B -> X(1.0) A -> C -> X(2.0)
这次X(1.0) X(2.0)路径长度相同了,因为B比C声明的早,所以取B依赖的X(1.0)版本
默认就是compile,什么都不配置也就是意味着compile。compile表示被依赖项目需要参与当前项目的编译,当然后续的测试,运行周期也参与其中,是一个比较强的依赖。打包的时候通常需要包含进去。
scope为test表示依赖项目仅仅参与测试相关的工作,包括测试代码的编译,执行。比较典型的如junit。
runntime表示被依赖项目无需参与项目的编译,不过后期的测试和运行周期需要其参与。与compile相比,跳过编译而已,说实话在终端的项目(非开源,企业内部系统)中,和compile区别不是很大。比较常见的如JSR×××的实现,对应的API jar是compile的,具体实现是runtime的,compile只需要知道接口就足够了。oracle jdbc驱动架包就是一个很好的例子,一般scope为runntime。另外runntime的依赖通常和optional搭配使用,optional为true。我可以用A实现,也可以用B实现。
provided意味着打包的时候可以不用包进去,别的设施(Web Container)会提供。事实上该依赖理论上可以参与编译,测试,运行等周期。相当于compile,但是在打包阶段做了exclude的动作。
scope使用provided,表示用于当前项目编译使用,不向下传递。
从参与度来说,也provided相同,不过被依赖项不会从maven仓库抓,而是从本地文件系统拿,一定需要配合systemPath属性使用。
A–>B–>C。当前项目为A,A依赖于B,B依赖于C。知道B在A项目中的scope,那么怎么知道C在A中的scope呢?答案是:
This is a placeholder page. Replace it with your own content.
This is the section landing page.
This is a placeholder page. Replace it with your own content.
Text can be bold, italic, or strikethrough. Links should be blue with no underlines (unless hovered over).
There should be whitespace between paragraphs. Vape migas chillwave sriracha poutine try-hard distillery. Tattooed shabby chic small batch, pabst art party heirloom letterpress air plant pop-up. Sustainable chia skateboard art party banjo cardigan normcore affogato vexillologist quinoa meggings man bun master cleanse shoreditch readymade. Yuccie prism four dollar toast tbh cardigan iPhone, tumblr listicle live-edge VHS. Pug lyft normcore hot chicken biodiesel, actually keffiyeh thundercats photo booth pour-over twee fam food truck microdosing banh mi. Vice activated charcoal raclette unicorn live-edge post-ironic. Heirloom vexillologist coloring book, beard deep v letterpress echo park humblebrag tilde.
90’s four loko seitan photo booth gochujang freegan tumeric listicle fam ugh humblebrag. Bespoke leggings gastropub, biodiesel brunch pug fashion axe meh swag art party neutra deep v chia. Enamel pin fanny pack knausgaard tofu, artisan cronut hammock meditation occupy master cleanse chartreuse lumbersexual. Kombucha kogi viral truffaut synth distillery single-origin coffee ugh slow-carb marfa selfies. Pitchfork schlitz semiotics fanny pack, ugh artisan vegan vaporware hexagon. Polaroid fixie post-ironic venmo wolf ramps kale chips.
There should be no margin above this first sentence.
Blockquotes should be a lighter gray with a border along the left side in the secondary color.
There should be no margin below this final sentence.
This is a normal paragraph following a header. Knausgaard kale chips snackwave microdosing cronut copper mug swag synth bitters letterpress glossier craft beer. Mumblecore bushwick authentic gochujang vegan chambray meditation jean shorts irony. Viral farm-to-table kale chips, pork belly palo santo distillery activated charcoal aesthetic jianbing air plant woke lomo VHS organic. Tattooed locavore succulents heirloom, small batch sriracha echo park DIY af. Shaman you probably haven’t heard of them copper mug, crucifix green juice vape single-origin coffee brunch actually. Mustache etsy vexillologist raclette authentic fam. Tousled beard humblebrag asymmetrical. I love turkey, I love my job, I love my friends, I love Chardonnay!
Deae legum paulatimque terra, non vos mutata tacet: dic. Vocant docuique me plumas fila quin afuerunt copia haec o neque.
On big screens, paragraphs and headings should not take up the full container width, but we want tables, code blocks and similar to take the full width.
Scenester tumeric pickled, authentic crucifix post-ironic fam freegan VHS pork belly 8-bit yuccie PBR&B. I love this life we live in.
This is a blockquote following a header. Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.
This is a code block following a header.
Next level leggings before they sold out, PBR&B church-key shaman echo park. Kale chips occupy godard whatever pop-up freegan pork belly selfies. Gastropub Belinda subway tile woke post-ironic seitan. Shabby chic man bun semiotics vape, chia messenger bag plaid cardigan.
| What | Follows |
|---|---|
| A table | A header |
| A table | A header |
| A table | A header |
There’s a horizontal rule above and below this.
Here is an unordered list:
And an ordered list:
And an unordered task list:
And a “mixed” task list:
And a nested list:
Definition lists can be used with Markdown syntax. Definition headers are bold.
Tables should have bold headings and alternating shaded rows.
| Artist | Album | Year |
|---|---|---|
| Michael Jackson | Thriller | 1982 |
| Prince | Purple Rain | 1984 |
| Beastie Boys | License to Ill | 1986 |
If a table is too wide, it should scroll horizontally.
| Artist | Album | Year | Label | Awards | Songs |
|---|---|---|---|---|---|
| Michael Jackson | Thriller | 1982 | Epic Records | Grammy Award for Album of the Year, American Music Award for Favorite Pop/Rock Album, American Music Award for Favorite Soul/R&B Album, Brit Award for Best Selling Album, Grammy Award for Best Engineered Album, Non-Classical | Wanna Be Startin’ Somethin’, Baby Be Mine, The Girl Is Mine, Thriller, Beat It, Billie Jean, Human Nature, P.Y.T. (Pretty Young Thing), The Lady in My Life |
| Prince | Purple Rain | 1984 | Warner Brothers Records | Grammy Award for Best Score Soundtrack for Visual Media, American Music Award for Favorite Pop/Rock Album, American Music Award for Favorite Soul/R&B Album, Brit Award for Best Soundtrack/Cast Recording, Grammy Award for Best Rock Performance by a Duo or Group with Vocal | Let’s Go Crazy, Take Me With U, The Beautiful Ones, Computer Blue, Darling Nikki, When Doves Cry, I Would Die 4 U, Baby I’m a Star, Purple Rain |
| Beastie Boys | License to Ill | 1986 | Mercury Records | noawardsbutthistablecelliswide | Rhymin & Stealin, The New Style, She’s Crafty, Posse in Effect, Slow Ride, Girls, (You Gotta) Fight for Your Right, No Sleep Till Brooklyn, Paul Revere, Hold It Now, Hit It, Brass Monkey, Slow and Low, Time to Get Ill |
Code snippets like var foo = "bar"; can be shown inline.
Also, this should vertically align with thisand this.
Code can also be shown in a block element.
foo := "bar";
bar := "foo";
Code can also use syntax highlighting.
func main() {
input := `var foo = "bar";`
lexer := lexers.Get("javascript")
iterator, _ := lexer.Tokenise(nil, input)
style := styles.Get("github")
formatter := html.New(html.WithLineNumbers())
var buff bytes.Buffer
formatter.Format(&buff, style, iterator)
fmt.Println(buff.String())
}
Long, single-line code blocks should not wrap. They should horizontally scroll if they are too long. This line should be long enough to demonstrate this.
Inline code inside table cells should still be distinguishable.
| Language | Code |
|---|---|
| Javascript | var foo = "bar"; |
| Ruby | foo = "bar"{ |
Small images should be shown at their actual size.
![]()
Large images should always scale down and fit in the content container.
![]()
The photo above of the Spruce Picea abies shoot with foliage buds: Bjørn Erik Pedersen, CC-BY-SA.
Add some sections here to see how the ToC looks like. Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.
Inguina genus: Anaphen post: lingua violente voce suae meus aetate diversi. Orbis unam nec flammaeque status deam Silenum erat et a ferrea. Excitus rigidum ait: vestro et Herculis convicia: nitidae deseruit coniuge Proteaque adiciam eripitur? Sitim noceat signa probat quidem. Sua longis fugatis quidem genae.
Tilde photo booth wayfarers cliche lomo intelligentsia man braid kombucha vaporware farm-to-table mixtape portland. PBR&B pickled cornhole ugh try-hard ethical subway tile. Fixie paleo intelligentsia pabst. Ennui waistcoat vinyl gochujang. Poutine salvia authentic affogato, chambray lumbersexual shabby chic.
Plaid hell of cred microdosing, succulents tilde pour-over. Offal shabby chic 3 wolf moon blue bottle raw denim normcore poutine pork belly.
Stumptown PBR&B keytar plaid street art, forage XOXO pitchfork selvage affogato green juice listicle pickled everyday carry hashtag. Organic sustainable letterpress sartorial scenester intelligentsia swag bushwick. Put a bird on it stumptown neutra locavore. IPhone typewriter messenger bag narwhal. Ennui cold-pressed seitan flannel keytar, single-origin coffee adaptogen occupy yuccie williamsburg chillwave shoreditch forage waistcoat.
This is the final element on the page and there should be no margin below this.
This is a placeholder page. Replace it with your own content.
Text can be bold, italic, or strikethrough. Links should be blue with no underlines (unless hovered over).
There should be whitespace between paragraphs. Vape migas chillwave sriracha poutine try-hard distillery. Tattooed shabby chic small batch, pabst art party heirloom letterpress air plant pop-up. Sustainable chia skateboard art party banjo cardigan normcore affogato vexillologist quinoa meggings man bun master cleanse shoreditch readymade. Yuccie prism four dollar toast tbh cardigan iPhone, tumblr listicle live-edge VHS. Pug lyft normcore hot chicken biodiesel, actually keffiyeh thundercats photo booth pour-over twee fam food truck microdosing banh mi. Vice activated charcoal raclette unicorn live-edge post-ironic. Heirloom vexillologist coloring book, beard deep v letterpress echo park humblebrag tilde.
90’s four loko seitan photo booth gochujang freegan tumeric listicle fam ugh humblebrag. Bespoke leggings gastropub, biodiesel brunch pug fashion axe meh swag art party neutra deep v chia. Enamel pin fanny pack knausgaard tofu, artisan cronut hammock meditation occupy master cleanse chartreuse lumbersexual. Kombucha kogi viral truffaut synth distillery single-origin coffee ugh slow-carb marfa selfies. Pitchfork schlitz semiotics fanny pack, ugh artisan vegan vaporware hexagon. Polaroid fixie post-ironic venmo wolf ramps kale chips.
There should be no margin above this first sentence.
Blockquotes should be a lighter gray with a border along the left side in the secondary color.
There should be no margin below this final sentence.
This is a normal paragraph following a header. Knausgaard kale chips snackwave microdosing cronut copper mug swag synth bitters letterpress glossier craft beer. Mumblecore bushwick authentic gochujang vegan chambray meditation jean shorts irony. Viral farm-to-table kale chips, pork belly palo santo distillery activated charcoal aesthetic jianbing air plant woke lomo VHS organic. Tattooed locavore succulents heirloom, small batch sriracha echo park DIY af. Shaman you probably haven’t heard of them copper mug, crucifix green juice vape single-origin coffee brunch actually. Mustache etsy vexillologist raclette authentic fam. Tousled beard humblebrag asymmetrical. I love turkey, I love my job, I love my friends, I love Chardonnay!
Deae legum paulatimque terra, non vos mutata tacet: dic. Vocant docuique me plumas fila quin afuerunt copia haec o neque.
On big screens, paragraphs and headings should not take up the full container width, but we want tables, code blocks and similar to take the full width.
Scenester tumeric pickled, authentic crucifix post-ironic fam freegan VHS pork belly 8-bit yuccie PBR&B. I love this life we live in.
This is a blockquote following a header. Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.
This is a code block following a header.
Next level leggings before they sold out, PBR&B church-key shaman echo park. Kale chips occupy godard whatever pop-up freegan pork belly selfies. Gastropub Belinda subway tile woke post-ironic seitan. Shabby chic man bun semiotics vape, chia messenger bag plaid cardigan.
| What | Follows |
|---|---|
| A table | A header |
| A table | A header |
| A table | A header |
There’s a horizontal rule above and below this.
Here is an unordered list:
And an ordered list:
And an unordered task list:
And a “mixed” task list:
And a nested list:
Definition lists can be used with Markdown syntax. Definition headers are bold.
Tables should have bold headings and alternating shaded rows.
| Artist | Album | Year |
|---|---|---|
| Michael Jackson | Thriller | 1982 |
| Prince | Purple Rain | 1984 |
| Beastie Boys | License to Ill | 1986 |
If a table is too wide, it should scroll horizontally.
| Artist | Album | Year | Label | Awards | Songs |
|---|---|---|---|---|---|
| Michael Jackson | Thriller | 1982 | Epic Records | Grammy Award for Album of the Year, American Music Award for Favorite Pop/Rock Album, American Music Award for Favorite Soul/R&B Album, Brit Award for Best Selling Album, Grammy Award for Best Engineered Album, Non-Classical | Wanna Be Startin’ Somethin’, Baby Be Mine, The Girl Is Mine, Thriller, Beat It, Billie Jean, Human Nature, P.Y.T. (Pretty Young Thing), The Lady in My Life |
| Prince | Purple Rain | 1984 | Warner Brothers Records | Grammy Award for Best Score Soundtrack for Visual Media, American Music Award for Favorite Pop/Rock Album, American Music Award for Favorite Soul/R&B Album, Brit Award for Best Soundtrack/Cast Recording, Grammy Award for Best Rock Performance by a Duo or Group with Vocal | Let’s Go Crazy, Take Me With U, The Beautiful Ones, Computer Blue, Darling Nikki, When Doves Cry, I Would Die 4 U, Baby I’m a Star, Purple Rain |
| Beastie Boys | License to Ill | 1986 | Mercury Records | noawardsbutthistablecelliswide | Rhymin & Stealin, The New Style, She’s Crafty, Posse in Effect, Slow Ride, Girls, (You Gotta) Fight for Your Right, No Sleep Till Brooklyn, Paul Revere, Hold It Now, Hit It, Brass Monkey, Slow and Low, Time to Get Ill |
Code snippets like var foo = "bar"; can be shown inline.
Also, this should vertically align with thisand this.
Code can also be shown in a block element.
foo := "bar";
bar := "foo";
Code can also use syntax highlighting.
func main() {
input := `var foo = "bar";`
lexer := lexers.Get("javascript")
iterator, _ := lexer.Tokenise(nil, input)
style := styles.Get("github")
formatter := html.New(html.WithLineNumbers())
var buff bytes.Buffer
formatter.Format(&buff, style, iterator)
fmt.Println(buff.String())
}
Long, single-line code blocks should not wrap. They should horizontally scroll if they are too long. This line should be long enough to demonstrate this.
Inline code inside table cells should still be distinguishable.
| Language | Code |
|---|---|
| Javascript | var foo = "bar"; |
| Ruby | foo = "bar"{ |
Small images should be shown at their actual size.
![]()
Large images should always scale down and fit in the content container.
![]()
The photo above of the Spruce Picea abies shoot with foliage buds: Bjørn Erik Pedersen, CC-BY-SA.
Add some sections here to see how the ToC looks like. Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.
Inguina genus: Anaphen post: lingua violente voce suae meus aetate diversi. Orbis unam nec flammaeque status deam Silenum erat et a ferrea. Excitus rigidum ait: vestro et Herculis convicia: nitidae deseruit coniuge Proteaque adiciam eripitur? Sitim noceat signa probat quidem. Sua longis fugatis quidem genae.
Tilde photo booth wayfarers cliche lomo intelligentsia man braid kombucha vaporware farm-to-table mixtape portland. PBR&B pickled cornhole ugh try-hard ethical subway tile. Fixie paleo intelligentsia pabst. Ennui waistcoat vinyl gochujang. Poutine salvia authentic affogato, chambray lumbersexual shabby chic.
Plaid hell of cred microdosing, succulents tilde pour-over. Offal shabby chic 3 wolf moon blue bottle raw denim normcore poutine pork belly.
Stumptown PBR&B keytar plaid street art, forage XOXO pitchfork selvage affogato green juice listicle pickled everyday carry hashtag. Organic sustainable letterpress sartorial scenester intelligentsia swag bushwick. Put a bird on it stumptown neutra locavore. IPhone typewriter messenger bag narwhal. Ennui cold-pressed seitan flannel keytar, single-origin coffee adaptogen occupy yuccie williamsburg chillwave shoreditch forage waistcoat.
This is the final element on the page and there should be no margin below this.
本节包含 Capa SDK 组件的 API 参考文档。
Capa 为云应用开发提供统一的 API 层。以下参考文档可用:
Capa API 规范遵循社区标准,定义在 cloud-runtimes-jvm 仓库中。
This is a placeholder page. Replace it with your own content.
Text can be bold, italic, or strikethrough. Links should be blue with no underlines (unless hovered over).
There should be whitespace between paragraphs. Vape migas chillwave sriracha poutine try-hard distillery. Tattooed shabby chic small batch, pabst art party heirloom letterpress air plant pop-up. Sustainable chia skateboard art party banjo cardigan normcore affogato vexillologist quinoa meggings man bun master cleanse shoreditch readymade. Yuccie prism four dollar toast tbh cardigan iPhone, tumblr listicle live-edge VHS. Pug lyft normcore hot chicken biodiesel, actually keffiyeh thundercats photo booth pour-over twee fam food truck microdosing banh mi. Vice activated charcoal raclette unicorn live-edge post-ironic. Heirloom vexillologist coloring book, beard deep v letterpress echo park humblebrag tilde.
90’s four loko seitan photo booth gochujang freegan tumeric listicle fam ugh humblebrag. Bespoke leggings gastropub, biodiesel brunch pug fashion axe meh swag art party neutra deep v chia. Enamel pin fanny pack knausgaard tofu, artisan cronut hammock meditation occupy master cleanse chartreuse lumbersexual. Kombucha kogi viral truffaut synth distillery single-origin coffee ugh slow-carb marfa selfies. Pitchfork schlitz semiotics fanny pack, ugh artisan vegan vaporware hexagon. Polaroid fixie post-ironic venmo wolf ramps kale chips.
There should be no margin above this first sentence.
Blockquotes should be a lighter gray with a border along the left side in the secondary color.
There should be no margin below this final sentence.
This is a normal paragraph following a header. Knausgaard kale chips snackwave microdosing cronut copper mug swag synth bitters letterpress glossier craft beer. Mumblecore bushwick authentic gochujang vegan chambray meditation jean shorts irony. Viral farm-to-table kale chips, pork belly palo santo distillery activated charcoal aesthetic jianbing air plant woke lomo VHS organic. Tattooed locavore succulents heirloom, small batch sriracha echo park DIY af. Shaman you probably haven’t heard of them copper mug, crucifix green juice vape single-origin coffee brunch actually. Mustache etsy vexillologist raclette authentic fam. Tousled beard humblebrag asymmetrical. I love turkey, I love my job, I love my friends, I love Chardonnay!
Deae legum paulatimque terra, non vos mutata tacet: dic. Vocant docuique me plumas fila quin afuerunt copia haec o neque.
On big screens, paragraphs and headings should not take up the full container width, but we want tables, code blocks and similar to take the full width.
Scenester tumeric pickled, authentic crucifix post-ironic fam freegan VHS pork belly 8-bit yuccie PBR&B. I love this life we live in.
This is a blockquote following a header. Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.
This is a code block following a header.
Next level leggings before they sold out, PBR&B church-key shaman echo park. Kale chips occupy godard whatever pop-up freegan pork belly selfies. Gastropub Belinda subway tile woke post-ironic seitan. Shabby chic man bun semiotics vape, chia messenger bag plaid cardigan.
| What | Follows |
|---|---|
| A table | A header |
| A table | A header |
| A table | A header |
There’s a horizontal rule above and below this.
Here is an unordered list:
And an ordered list:
And an unordered task list:
And a “mixed” task list:
And a nested list:
Definition lists can be used with Markdown syntax. Definition headers are bold.
Tables should have bold headings and alternating shaded rows.
| Artist | Album | Year |
|---|---|---|
| Michael Jackson | Thriller | 1982 |
| Prince | Purple Rain | 1984 |
| Beastie Boys | License to Ill | 1986 |
If a table is too wide, it should scroll horizontally.
| Artist | Album | Year | Label | Awards | Songs |
|---|---|---|---|---|---|
| Michael Jackson | Thriller | 1982 | Epic Records | Grammy Award for Album of the Year, American Music Award for Favorite Pop/Rock Album, American Music Award for Favorite Soul/R&B Album, Brit Award for Best Selling Album, Grammy Award for Best Engineered Album, Non-Classical | Wanna Be Startin’ Somethin’, Baby Be Mine, The Girl Is Mine, Thriller, Beat It, Billie Jean, Human Nature, P.Y.T. (Pretty Young Thing), The Lady in My Life |
| Prince | Purple Rain | 1984 | Warner Brothers Records | Grammy Award for Best Score Soundtrack for Visual Media, American Music Award for Favorite Pop/Rock Album, American Music Award for Favorite Soul/R&B Album, Brit Award for Best Soundtrack/Cast Recording, Grammy Award for Best Rock Performance by a Duo or Group with Vocal | Let’s Go Crazy, Take Me With U, The Beautiful Ones, Computer Blue, Darling Nikki, When Doves Cry, I Would Die 4 U, Baby I’m a Star, Purple Rain |
| Beastie Boys | License to Ill | 1986 | Mercury Records | noawardsbutthistablecelliswide | Rhymin & Stealin, The New Style, She’s Crafty, Posse in Effect, Slow Ride, Girls, (You Gotta) Fight for Your Right, No Sleep Till Brooklyn, Paul Revere, Hold It Now, Hit It, Brass Monkey, Slow and Low, Time to Get Ill |
Code snippets like var foo = "bar"; can be shown inline.
Also, this should vertically align with thisand this.
Code can also be shown in a block element.
foo := "bar";
bar := "foo";
Code can also use syntax highlighting.
func main() {
input := `var foo = "bar";`
lexer := lexers.Get("javascript")
iterator, _ := lexer.Tokenise(nil, input)
style := styles.Get("github")
formatter := html.New(html.WithLineNumbers())
var buff bytes.Buffer
formatter.Format(&buff, style, iterator)
fmt.Println(buff.String())
}
Long, single-line code blocks should not wrap. They should horizontally scroll if they are too long. This line should be long enough to demonstrate this.
Inline code inside table cells should still be distinguishable.
| Language | Code |
|---|---|
| Javascript | var foo = "bar"; |
| Ruby | foo = "bar"{ |
Small images should be shown at their actual size.
![]()
Large images should always scale down and fit in the content container.
![]()
The photo above of the Spruce Picea abies shoot with foliage buds: Bjørn Erik Pedersen, CC-BY-SA.
感谢您对Capa的支持!
Capa 基于 Apache 2.0 许可发布,遵循标准的 Github 开发流程。 本文档描述了如何使用 Github Issue 和 Pull Request 对Capa做出贡献。
范例:
源类的全限定名为 com.api.Matching
源文件路径 src/main/java/com/api/Matching.java
UT文件路径 src/test/java/com/api/MatchingTest.java
范例:
源方法名为 matching()
UT方法命名为 testMatching_Success()/testMatching_SuccessWhenResultGreaterThanZero()/testMatching_FailWhenThrowException()
<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
本文档描述了如何为 Capa 文档库做出贡献。文档库使用 Markdown 语法编写。已发布到 capa-cloud/capa.io。
Capa 文档库使用 Hugo 的 Docsy 主题构建。
文件统一放在 content/ 目录下,其中中文文档存放于 content/zh ,英文文档存放于 content/en。
如果需要新增文档,需要按照目录结构新增文件夹和.md文件。

图片统一放在 content/images/ 目录下,其中图片目录结构与所引用的 md 文件的目录保持一致。需要选用清晰且与背景适配的图片。
文档中统一使用全路径来引用图片,Url前缀 https://raw.githubusercontent.com/capa-cloud/capa.io/master/content/images 。
例如,引入下图的图片(contribution_file.png),Markdown写法如下:

