blob: 086578c23149781b73785a0a9c6f214cac8ad845 [file] [log] [blame]
{"config":{"indexing":"full","lang":["en"],"min_search_length":3,"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"Overview Apache ServiceComb Java Chassis provides developers with a Java SDK to quickly build microservices. It contains the following features: Multiple development styles, REST (JAX-RS, Spring MVC) and RPC Multiple communication protocols, HTTP over Vert.x, Http Over Servlet, Highway, etc. Uniform service providers, service consumer handler, and contract-based out-of-the-box service governance capabilities For other versions, please check the following table. version link notes 2.8.x \u4e2d\u6587 , English 2.8.x \u4e2d\u6587 , English hosted by gitee pages","title":"Introduction"},{"location":"#overview","text":"Apache ServiceComb Java Chassis provides developers with a Java SDK to quickly build microservices. It contains the following features: Multiple development styles, REST (JAX-RS, Spring MVC) and RPC Multiple communication protocols, HTTP over Vert.x, Http Over Servlet, Highway, etc. Uniform service providers, service consumer handler, and contract-based out-of-the-box service governance capabilities For other versions, please check the following table. version link notes 2.8.x \u4e2d\u6587 , English 2.8.x \u4e2d\u6587 , English hosted by gitee pages","title":"Overview"},{"location":"featured-topics/","text":"","title":"Featured topics"},{"location":"build-consumer/3rd-party-service-invoke/","text":"Invoking 3rd party REST service Concept Description ServiceComb allows users to register the information of 3rd party REST service, including endpoint and swagger, so that users can invoke 3rd party services like invoking ServiceComb provider services. Using this feature, all the requests sent to 3rd party service will be processed by consumer handler chain and HttpClientFilters, which means this feature allows service governance function on invoking 3rd party service, and other ServiceComb custom extension mechanism is also supported. Sample Code Assume that there is a REST 3rd party service, whose listen port is 8080, and rest interface contract is like below: ```yaml swagger: \"2.0\" info: version: \"0.0.1\" title: \"3rd party REST service for example\" basePath: \"/rest\" consumes: - \"application/json\" produces: - \"text/plain\" paths: /{pathVar}: get: operationId: \"testPathVar\" parameters: - name: \"pathVar\" in: \"path\" required: true type: \"string\" responses: 200: description: \"response of 200, return \\\"Received, OK. [${pathVar}]\\\"\" schema: type: \"string\" ``` To invoke this service, a java interface class should be written according to the rest contract and annotated by rest annotations. The way to write java interface class is similar to writing SpringMVC or JAX-RS style ServiceComb provider service. Interface code is like below: java @Path(\"/rest\") @Api(produces = MediaType.TEXT_PLAIN) public interface VertxServerIntf { @Path(\"/{pathVar}\") @GET String testPathVar(@PathParam(\"pathVar\") String pathVar); } Register the information of 3rd party rest service on consumer side: java String endpoint = \"rest://127.0.0.1:8080\"; RegistryUtils.getServiceRegistry().registerMicroserviceMappingByEndpoints( // 3rd party rest service name, you can specify the name on your need as long as you obey the microservice naming rule \"thirdPartyService\", // service version \"0.0.1\", // list of endpoints Collections.singletonList(endpoint), // java interface class to generate swagger schema ThirdPartyRestServiceInterface.class ); Invoke 3rd party rest service in the way similar to invoking ServiceComb provider service. Here is a RPC style invoking example: ```java // declare rpc reference to 3rd party rest service, schemaId is the same as microservice name @RpcReference(microserviceName = \"thirdPartyService\", schemaId = \"thirdPartyService\") ThirdPartyRestServiceInterface thirdPartyRestService; @RequestMapping(path = \"/{pathVar}\", method = RequestMethod.GET) public String testInvoke(@PathVariable(name = \"pathVar\") String pathVar) { LOGGER.info(\"testInvoke() is called, pathVar = [{}]\", pathVar); // invoke 3rd party rest service String response = thirdPartyRestService.testPathVar(pathVar); LOGGER.info(\"testInvoke() response = [{}]\", response); return response; } ``` Service governance on invoking 3rd party REST service The service governance configuration on invoking 3rd party REST service is similar to the scenario that ServiceComb consumer invokes ServiceComb provider. Take the rate limiting policy for example, the configuration of consumer side microservice.yaml is like below: yaml servicecomb: flowcontrol: Consumer: qps: enabled: true limit: thirdPartyService: 1 As the config above, the rate to send request to the service named as \"thirdPartyService\", which is the 3rd party rest service, is limited to 1QPS. When request rate is above 1QPS, consumer will get an InvocationException indicating 429 Too Many Requests error. Cautions: - endpoint is prefixed with rest , instead of http . You can refer the endpoints registered to service center to write it. - One 3rd party REST service can hold multiple endpoints. Consumer side load balance function is supported. - Currently the information of a 3rd party service can only be initialized for once. i.e. adding, deleting and modifying is not supported.","title":"Invoke 3rd-party REST services"},{"location":"build-consumer/3rd-party-service-invoke/#invoking-3rd-party-rest-service","text":"","title":"Invoking 3rd party REST service"},{"location":"build-consumer/3rd-party-service-invoke/#concept-description","text":"ServiceComb allows users to register the information of 3rd party REST service, including endpoint and swagger, so that users can invoke 3rd party services like invoking ServiceComb provider services. Using this feature, all the requests sent to 3rd party service will be processed by consumer handler chain and HttpClientFilters, which means this feature allows service governance function on invoking 3rd party service, and other ServiceComb custom extension mechanism is also supported.","title":"Concept Description"},{"location":"build-consumer/3rd-party-service-invoke/#sample-code","text":"Assume that there is a REST 3rd party service, whose listen port is 8080, and rest interface contract is like below: ```yaml swagger: \"2.0\" info: version: \"0.0.1\" title: \"3rd party REST service for example\" basePath: \"/rest\" consumes: - \"application/json\" produces: - \"text/plain\" paths: /{pathVar}: get: operationId: \"testPathVar\" parameters: - name: \"pathVar\" in: \"path\" required: true type: \"string\" responses: 200: description: \"response of 200, return \\\"Received, OK. [${pathVar}]\\\"\" schema: type: \"string\" ``` To invoke this service, a java interface class should be written according to the rest contract and annotated by rest annotations. The way to write java interface class is similar to writing SpringMVC or JAX-RS style ServiceComb provider service. Interface code is like below: java @Path(\"/rest\") @Api(produces = MediaType.TEXT_PLAIN) public interface VertxServerIntf { @Path(\"/{pathVar}\") @GET String testPathVar(@PathParam(\"pathVar\") String pathVar); } Register the information of 3rd party rest service on consumer side: java String endpoint = \"rest://127.0.0.1:8080\"; RegistryUtils.getServiceRegistry().registerMicroserviceMappingByEndpoints( // 3rd party rest service name, you can specify the name on your need as long as you obey the microservice naming rule \"thirdPartyService\", // service version \"0.0.1\", // list of endpoints Collections.singletonList(endpoint), // java interface class to generate swagger schema ThirdPartyRestServiceInterface.class ); Invoke 3rd party rest service in the way similar to invoking ServiceComb provider service. Here is a RPC style invoking example: ```java // declare rpc reference to 3rd party rest service, schemaId is the same as microservice name @RpcReference(microserviceName = \"thirdPartyService\", schemaId = \"thirdPartyService\") ThirdPartyRestServiceInterface thirdPartyRestService; @RequestMapping(path = \"/{pathVar}\", method = RequestMethod.GET) public String testInvoke(@PathVariable(name = \"pathVar\") String pathVar) { LOGGER.info(\"testInvoke() is called, pathVar = [{}]\", pathVar); // invoke 3rd party rest service String response = thirdPartyRestService.testPathVar(pathVar); LOGGER.info(\"testInvoke() response = [{}]\", response); return response; } ``` Service governance on invoking 3rd party REST service The service governance configuration on invoking 3rd party REST service is similar to the scenario that ServiceComb consumer invokes ServiceComb provider. Take the rate limiting policy for example, the configuration of consumer side microservice.yaml is like below: yaml servicecomb: flowcontrol: Consumer: qps: enabled: true limit: thirdPartyService: 1 As the config above, the rate to send request to the service named as \"thirdPartyService\", which is the 3rd party rest service, is limited to 1QPS. When request rate is above 1QPS, consumer will get an InvocationException indicating 429 Too Many Requests error. Cautions: - endpoint is prefixed with rest , instead of http . You can refer the endpoints registered to service center to write it. - One 3rd party REST service can hold multiple endpoints. Consumer side load balance function is supported. - Currently the information of a 3rd party service can only be initialized for once. i.e. adding, deleting and modifying is not supported.","title":"Sample Code"},{"location":"build-consumer/circuit-breaker/","text":"Circuit Break Policy Scenario Circuit brake policy can configure ServiceComb fallback capability, you can configure conditions under which service will stop send request after circuit break policy configured. Configuration Circuit break is part of fallback policy when a service request is abnormal, relevant concept such as isolation and fault tolerance please refer to fallback policy \u3002","title":"Circuit Breaker"},{"location":"build-consumer/circuit-breaker/#circuit-break-policy","text":"","title":"Circuit Break Policy"},{"location":"build-consumer/circuit-breaker/#scenario","text":"Circuit brake policy can configure ServiceComb fallback capability, you can configure conditions under which service will stop send request after circuit break policy configured.","title":"Scenario"},{"location":"build-consumer/circuit-breaker/#configuration","text":"Circuit break is part of fallback policy when a service request is abnormal, relevant concept such as isolation and fault tolerance please refer to fallback policy \u3002","title":"Configuration"},{"location":"build-consumer/code-first/","text":"Scene Description Service consumers can store contracts in the project directory without having to explicitly do so, and when the program starts, the ServiceComb framework automatically pulls the contract information from the service center based on the microservice name and version number of the service provider configured in the microservice.yaml file. Involving API The use of implicit contracts can be used for both RestTemplate and transparent RPC service development models. For the development method using RestTemplate, see 4.3 Developing Service Consumers with RestTemplate. Sample Code This section shows how to develop service consumers using implicit contracts, using transparent RPC development patterns as an example. The sample code for the service consumer is as follows: import org.springframework.stereotype.Component; import org.apache.servicecomb.foundation.common.utils.BeanUtils; import org.apache.servicecomb.foundation.common.utils.Log4jUtils; import org.apache.servicecomb.provider.pojo.RpcReference; import org.apache.servicecomb.samples.common.schema.Hello; import org.apache.servicecomb.samples.common.schema.models.Person; @Component public class CodeFirstConsumerMain { @RpcReference(microserviceName = \"codefirst\", schemaId = \"codeFirstHello\") private static Hello hello; public static void main(String[] args) throws Exception { init(); System.out.println(hello.sayHi(\"Java Chassis\")); Person person = new Person(); person.setName(\"ServiceComb/Java Chassis\"); System.out.println(hello.sayHello(person)); } public static void init() throws Exception { Log4jUtils.init(); BeanUtils.init(); } } In the code above, the service consumer has taken the service interface Hello of the service provider and declared a Hello type member in the code. By using the RPCReference annotation on hello to specify the microservice name and schemaId, the ServiceComb framework can be in When the program starts, the corresponding service provider instance information is obtained from the service center and a proxy is generated to be injected into the hello. The user can invoke the remote service as if it were a local class.","title":"Code first"},{"location":"build-consumer/code-first/#scene-description","text":"Service consumers can store contracts in the project directory without having to explicitly do so, and when the program starts, the ServiceComb framework automatically pulls the contract information from the service center based on the microservice name and version number of the service provider configured in the microservice.yaml file.","title":"Scene Description"},{"location":"build-consumer/code-first/#involving-api","text":"The use of implicit contracts can be used for both RestTemplate and transparent RPC service development models. For the development method using RestTemplate, see 4.3 Developing Service Consumers with RestTemplate.","title":"Involving API"},{"location":"build-consumer/code-first/#sample-code","text":"This section shows how to develop service consumers using implicit contracts, using transparent RPC development patterns as an example. The sample code for the service consumer is as follows: import org.springframework.stereotype.Component; import org.apache.servicecomb.foundation.common.utils.BeanUtils; import org.apache.servicecomb.foundation.common.utils.Log4jUtils; import org.apache.servicecomb.provider.pojo.RpcReference; import org.apache.servicecomb.samples.common.schema.Hello; import org.apache.servicecomb.samples.common.schema.models.Person; @Component public class CodeFirstConsumerMain { @RpcReference(microserviceName = \"codefirst\", schemaId = \"codeFirstHello\") private static Hello hello; public static void main(String[] args) throws Exception { init(); System.out.println(hello.sayHi(\"Java Chassis\")); Person person = new Person(); person.setName(\"ServiceComb/Java Chassis\"); System.out.println(hello.sayHello(person)); } public static void init() throws Exception { Log4jUtils.init(); BeanUtils.init(); } } In the code above, the service consumer has taken the service interface Hello of the service provider and declared a Hello type member in the code. By using the RPCReference annotation on hello to specify the microservice name and schemaId, the ServiceComb framework can be in When the program starts, the corresponding service provider instance information is obtained from the service center and a proxy is generated to be injected into the hello. The user can invoke the remote service as if it were a local class.","title":"Sample Code"},{"location":"build-consumer/common-configuration/","text":"Consumer's common configuration Request timed out Configuration servicecomb.request.timeout Default 30000\uff0cunit is milliseconds Description When the Consumer transport layer starts transmitting, it starts timing. If the response is not received within the specified time, the processing is timeout. Designated transmission channel Configuration servicecomb.references.${target microservice name}.transport servicecomb.references.transport Supports both global and micro-service level two-level control Default none Description If the target micro-service simultaneously opens the access capabilities of multiple transports, and the Consumer also deploys multiple transports at the same time, when the Consumer invokes the micro-service as a Consumer, you only want to use one of the transports, you can specify this configuration If not configured, use multiple transports in turn Specify the version rule for the target instance Configuration servicecomb.references.${target microservice name}.version-rule servicecomb.references.version-rule Supports both global and micro-service level two-level control Default latest Description The version rule for the target instance supports the following rules: The latest version of\uff1a latest Greater than the specified version, for example: 1.0.0+ Specify the version range, for example: 1.0.0-2.0.0, which means greater than or equal to version 1.0.0 and less than version 2.0.0 Exact version, for example: 1.0.0","title":"Consumer common configuration"},{"location":"build-consumer/common-configuration/#consumers-common-configuration","text":"Request timed out Configuration servicecomb.request.timeout Default 30000\uff0cunit is milliseconds Description When the Consumer transport layer starts transmitting, it starts timing. If the response is not received within the specified time, the processing is timeout. Designated transmission channel Configuration servicecomb.references.${target microservice name}.transport servicecomb.references.transport Supports both global and micro-service level two-level control Default none Description If the target micro-service simultaneously opens the access capabilities of multiple transports, and the Consumer also deploys multiple transports at the same time, when the Consumer invokes the micro-service as a Consumer, you only want to use one of the transports, you can specify this configuration If not configured, use multiple transports in turn Specify the version rule for the target instance Configuration servicecomb.references.${target microservice name}.version-rule servicecomb.references.version-rule Supports both global and micro-service level two-level control Default latest Description The version rule for the target instance supports the following rules: The latest version of\uff1a latest Greater than the specified version, for example: 1.0.0+ Specify the version range, for example: 1.0.0-2.0.0, which means greater than or equal to version 1.0.0 and less than version 2.0.0 Exact version, for example: 1.0.0","title":"Consumer's common configuration"},{"location":"build-consumer/develop-consumer-using-rpc/","text":"Develop consumer with transparent RPC Concepts The transparent RPC allows user to access services like a local call through a simple java interface. Transparent RPC is just a development mode: Not associated with highway or RESTful transport The RPC does not rely on producers' development mode(transparent RPC/Jax-RS or SpringMVC) The RPC works even if the producer doesn't implement the interface. The transparent RPC is similar to spring cloud's feign, but simpler because there is no need to add any RESTful annotations in interface. Declare PRC by @RpcReference in spring bean @Component public class SomeBean { ...... @RpcReference(microserviceName = \"helloService\", schemaId = \"helloSchema\") private Hello hello; ...... } Declare by API without spring bean Hello hello = Invoker.createProxy(\"helloService\", \"helloSchema\", Hello.class); reactive Just use jdk's CompletableFuture to wrap the return value: interface Hello { CompletableFuture<String> sayHi(String name); } In the same interface, you can declare both the reactive and synchronous prototypes of the same method. It is illegal in java that the method name is the same with the operationId in the contract while the return value type is different, so you need to modify the method name and declare the real operationId through the swagger annotation. interface Hello { String sayHi(String name); @ApiOperation(nickname = \"sayHi\", value = \"reactive method for sayHi\") CompletableFuture<String> asyncSayHi(String name); }","title":"Using with RPC"},{"location":"build-consumer/develop-consumer-using-rpc/#develop-consumer-with-transparent-rpc","text":"","title":"Develop consumer with transparent RPC"},{"location":"build-consumer/develop-consumer-using-rpc/#concepts","text":"The transparent RPC allows user to access services like a local call through a simple java interface. Transparent RPC is just a development mode: Not associated with highway or RESTful transport The RPC does not rely on producers' development mode(transparent RPC/Jax-RS or SpringMVC) The RPC works even if the producer doesn't implement the interface. The transparent RPC is similar to spring cloud's feign, but simpler because there is no need to add any RESTful annotations in interface.","title":"Concepts"},{"location":"build-consumer/develop-consumer-using-rpc/#declare-prc-by-rpcreference-in-spring-bean","text":"@Component public class SomeBean { ...... @RpcReference(microserviceName = \"helloService\", schemaId = \"helloSchema\") private Hello hello; ...... }","title":"Declare PRC by @RpcReference in spring bean"},{"location":"build-consumer/develop-consumer-using-rpc/#declare-by-api-without-spring-bean","text":"Hello hello = Invoker.createProxy(\"helloService\", \"helloSchema\", Hello.class);","title":"Declare by API without spring bean"},{"location":"build-consumer/develop-consumer-using-rpc/#reactive","text":"Just use jdk's CompletableFuture to wrap the return value: interface Hello { CompletableFuture<String> sayHi(String name); } In the same interface, you can declare both the reactive and synchronous prototypes of the same method. It is illegal in java that the method name is the same with the operationId in the contract while the return value type is different, so you need to modify the method name and declare the real operationId through the swagger annotation. interface Hello { String sayHi(String name); @ApiOperation(nickname = \"sayHi\", value = \"reactive method for sayHi\") CompletableFuture<String> asyncSayHi(String name); }","title":"reactive"},{"location":"build-consumer/diao-yong-kong-zhi/","text":"","title":"Diao yong kong zhi"},{"location":"build-consumer/fault-injection/","text":"Fault Injection Scenario The user via fault injection on the consumer side to set the delay and error of the request to the specified microservice and its trigger probability. Precautions The delay time for delay injection requests is unified to the millisecond level. Configuration instructions The fault injection configuration is in the microservice.yaml file. The related configuration items are shown in the following table. To enable fault injection in the service consumer, you need to configure the consumer fault injection handler in the processing chain. The configuration example is as follows: servicecomb: handler: chain: Consumer: default: loadbalance,fault-injection-consumer Fault injection configuration item description [scope] represents the effective scope of the fault injection. The configurable value includes the global configuration _global or the service name of the microservice [ServiceName]. [protocol] represents the communication protocol used, and configurable values \u200b\u200binclude rest or highway. | Configuration Item | Default Value | Range of Value | Required | Meaning | | :--- | :--- | :--- | :--- | :--- | :--- | | servicecomb.governance.Consumer.[scope].policy.fault.protocols.[protocol].delay.fixedDelay | None | (0,9223372036854775807], Long Shaping | No | Consumer Send Delay Injection Request Delay time | current time unit is milliseconds | | servicecomb.governance.Consumer.[scope].policy.fault.protocols.[protocol].delay.percent | 100 | (0,100], Shaping | No | Trigger Probability of Sending Delay Injection Requests by Consumers | | | servicecomb.governance.Consumer.[ServiceName].schemas.[schema].policy.fault.protocols.[protocol].delay.fixedDelay | None | (0,9223372036854775807], Long Shaping| No | Delay time for delay injection request sent by the consumer to the corresponding schema | Support for schema level configuration | | servicecomb.governance.Consumer.[ServiceName].schemas.[schema].policy.fault.protocols.[protocol].delay.percent | 100 | (0,100],Plastic| No| Consumer Trigger probability of a delayed injection request sent by the end to the corresponding schema | Support for schema level configuration | | servicecomb.governance.Consumer.[ServiceName].schemas.[schema].operations.[operation].policy.fault.protocols.[protocol].delay.fixedDelay | None | (0 ,9223372036854775807],long shaping| no|delay time of delay injection request sent by the consumer to the corresponding operation | support operation level configuration | | servicecomb.governance.Consumer.[ServiceName].schemas.[schema].operations.[operation].policy.fault.protocols.[protocol].delay.percent | 100 | (0,100 ], shaping|no| trigger probability of delay injection request sent by the consumer to the corresponding operation | support operation level configuration | | servicecomb.governance.Consumer.[scope].policy.fault.protocols.[protocol].abort.httpStatus | None | (100,999], Shaping | No | The http error sent by the Consumer to send an error injection request Code| | | servicecomb.governance.Consumer.[scope].policy.fault.protocols.[protocol].abort.percent | 100 | (0,100], Shaping | No | Trigger Probability of Sending Error Injection Requests by Consumers | | | servicecomb.governance.Consumer.[ServiceName].schemas.[schema].policy.fault.protocols.[protocol].abort.httpStatus | None | (100,999],Plastic| No| Consumer Http error code sent by the end to the corresponding schema error injection request | Support schema level configuration | | servicecomb.governance.Consumer.[ServiceName].schemas.[schema].policy.fault.protocols.[protocol].abort.percent | 100 | (0,100],Plastic| No| Consumer Trigger probability of error injection request sent by the end to the corresponding schema | Support schema level configuration | | servicecomb.governance.Consumer.[ServiceName].schemas.[schema].operations.[operation].policy.fault.protocols.[protocol].abort.httpStatus | None | (100,999 ], shaping | No | http error code sent by the consumer to the error injection request of the corresponding operation | Support operation level configuration | | servicecomb.governance.Consumer.[ServiceName].schemas.[schema].operations.[operation].policy.fault.protocols.[protocol].abort.percent | 100 | (0,100 ], shaping | No | Trigger probability of error injection request sent by the consumer to the corresponding operation | Support operation level configuration | Sample Code servicecomb: governance: Consumer: _global: policy: fault: protocols: rest: delay: fixedDelay: 5000 percent: 10 servicecomb: governance: Consumer: ServerFaultTest: schemas: schema: operations: operation: policy: fault: protocols: rest: abort: httpStatus: 421 percent: 100","title":"Fault Injection"},{"location":"build-consumer/fault-injection/#fault-injection","text":"","title":"Fault Injection"},{"location":"build-consumer/fault-injection/#scenario","text":"The user via fault injection on the consumer side to set the delay and error of the request to the specified microservice and its trigger probability.","title":"Scenario"},{"location":"build-consumer/fault-injection/#precautions","text":"The delay time for delay injection requests is unified to the millisecond level.","title":"Precautions"},{"location":"build-consumer/fault-injection/#configuration-instructions","text":"The fault injection configuration is in the microservice.yaml file. The related configuration items are shown in the following table. To enable fault injection in the service consumer, you need to configure the consumer fault injection handler in the processing chain. The configuration example is as follows: servicecomb: handler: chain: Consumer: default: loadbalance,fault-injection-consumer Fault injection configuration item description [scope] represents the effective scope of the fault injection. The configurable value includes the global configuration _global or the service name of the microservice [ServiceName]. [protocol] represents the communication protocol used, and configurable values \u200b\u200binclude rest or highway. | Configuration Item | Default Value | Range of Value | Required | Meaning | | :--- | :--- | :--- | :--- | :--- | :--- | | servicecomb.governance.Consumer.[scope].policy.fault.protocols.[protocol].delay.fixedDelay | None | (0,9223372036854775807], Long Shaping | No | Consumer Send Delay Injection Request Delay time | current time unit is milliseconds | | servicecomb.governance.Consumer.[scope].policy.fault.protocols.[protocol].delay.percent | 100 | (0,100], Shaping | No | Trigger Probability of Sending Delay Injection Requests by Consumers | | | servicecomb.governance.Consumer.[ServiceName].schemas.[schema].policy.fault.protocols.[protocol].delay.fixedDelay | None | (0,9223372036854775807], Long Shaping| No | Delay time for delay injection request sent by the consumer to the corresponding schema | Support for schema level configuration | | servicecomb.governance.Consumer.[ServiceName].schemas.[schema].policy.fault.protocols.[protocol].delay.percent | 100 | (0,100],Plastic| No| Consumer Trigger probability of a delayed injection request sent by the end to the corresponding schema | Support for schema level configuration | | servicecomb.governance.Consumer.[ServiceName].schemas.[schema].operations.[operation].policy.fault.protocols.[protocol].delay.fixedDelay | None | (0 ,9223372036854775807],long shaping| no|delay time of delay injection request sent by the consumer to the corresponding operation | support operation level configuration | | servicecomb.governance.Consumer.[ServiceName].schemas.[schema].operations.[operation].policy.fault.protocols.[protocol].delay.percent | 100 | (0,100 ], shaping|no| trigger probability of delay injection request sent by the consumer to the corresponding operation | support operation level configuration | | servicecomb.governance.Consumer.[scope].policy.fault.protocols.[protocol].abort.httpStatus | None | (100,999], Shaping | No | The http error sent by the Consumer to send an error injection request Code| | | servicecomb.governance.Consumer.[scope].policy.fault.protocols.[protocol].abort.percent | 100 | (0,100], Shaping | No | Trigger Probability of Sending Error Injection Requests by Consumers | | | servicecomb.governance.Consumer.[ServiceName].schemas.[schema].policy.fault.protocols.[protocol].abort.httpStatus | None | (100,999],Plastic| No| Consumer Http error code sent by the end to the corresponding schema error injection request | Support schema level configuration | | servicecomb.governance.Consumer.[ServiceName].schemas.[schema].policy.fault.protocols.[protocol].abort.percent | 100 | (0,100],Plastic| No| Consumer Trigger probability of error injection request sent by the end to the corresponding schema | Support schema level configuration | | servicecomb.governance.Consumer.[ServiceName].schemas.[schema].operations.[operation].policy.fault.protocols.[protocol].abort.httpStatus | None | (100,999 ], shaping | No | http error code sent by the consumer to the error injection request of the corresponding operation | Support operation level configuration | | servicecomb.governance.Consumer.[ServiceName].schemas.[schema].operations.[operation].policy.fault.protocols.[protocol].abort.percent | 100 | (0,100 ], shaping | No | Trigger probability of error injection request sent by the consumer to the corresponding operation | Support operation level configuration |","title":"Configuration instructions"},{"location":"build-consumer/fault-injection/#sample-code","text":"servicecomb: governance: Consumer: _global: policy: fault: protocols: rest: delay: fixedDelay: 5000 percent: 10 servicecomb: governance: Consumer: ServerFaultTest: schemas: schema: operations: operation: policy: fault: protocols: rest: abort: httpStatus: 421 percent: 100","title":"Sample Code"},{"location":"build-consumer/flow-control/","text":"Flow Control Policy Scenario You can limit the frequency of request send to specific microservice when flow control was enables in consumer service. Precaution See detail info at Service Configurations \u3002 Configuration Flow control policy configuration is in microservice.yaml file. You need to configure consumer handler in chain of service. See example blow: servicecomb: handler: chain: Consumer: default: qps-flowcontrol-consumer Configuration items of QPS: Configuration Item Default Value Value Range Mandatory Description Remark servicecomb.flowcontrol.Consumer.qps.enabled true Boolean No Specifies whether consumers flowcontrol enables. - servicecomb.flowcontrol.Consumer.qps.limit.[ServiceName].[Schema].[operation] 2147483647 (max int) (0,2147483647], Integer No Specifies number of requests per second. Support three level configurations: microservice\u3001schema\u3001operation.","title":"Flow Control"},{"location":"build-consumer/flow-control/#flow-control-policy","text":"","title":"Flow Control Policy"},{"location":"build-consumer/flow-control/#scenario","text":"You can limit the frequency of request send to specific microservice when flow control was enables in consumer service.","title":"Scenario"},{"location":"build-consumer/flow-control/#precaution","text":"See detail info at Service Configurations \u3002","title":"Precaution"},{"location":"build-consumer/flow-control/#configuration","text":"Flow control policy configuration is in microservice.yaml file. You need to configure consumer handler in chain of service. See example blow: servicecomb: handler: chain: Consumer: default: qps-flowcontrol-consumer Configuration items of QPS: Configuration Item Default Value Value Range Mandatory Description Remark servicecomb.flowcontrol.Consumer.qps.enabled true Boolean No Specifies whether consumers flowcontrol enables. - servicecomb.flowcontrol.Consumer.qps.limit.[ServiceName].[Schema].[operation] 2147483647 (max int) (0,2147483647], Integer No Specifies number of requests per second. Support three level configurations: microservice\u3001schema\u3001operation.","title":"Configuration"},{"location":"build-consumer/invoke-control/","text":"Circuit Break Policy Circuit brake policy can configure ServiceComb fallback capability, you can configure conditions under which service will stop send request after circuit break policy configured. Flow Control Policy You can limit the frequency of request send to specific microservice when flow control was enables in consumer service. Fault Injection The user via fault injection on the consumer side to set the delay and error of the request to the specified microservice and its trigger probability.","title":"Invoke control"},{"location":"build-consumer/invoke-control/#circuit-break-policy","text":"Circuit brake policy can configure ServiceComb fallback capability, you can configure conditions under which service will stop send request after circuit break policy configured.","title":"Circuit Break Policy"},{"location":"build-consumer/invoke-control/#flow-control-policy","text":"You can limit the frequency of request send to specific microservice when flow control was enables in consumer service.","title":"Flow Control Policy"},{"location":"build-consumer/invoke-control/#fault-injection","text":"The user via fault injection on the consumer side to set the delay and error of the request to the specified microservice and its trigger probability.","title":"Fault Injection"},{"location":"build-consumer/using-AsyncRestTemplate/","text":"Develop consumer with AsyncRestTemplate Concepts AsyncRestTemplate allows users to make asynchronous service calls. The logic is similar to restTemplate, except that the service is called asynchronously. Sample code The AsyncRestTemplate instance is created and retrieved via new CseAsyncRestTemplate() , which is then used to make service calls through a custom URL. Spring MVC client sample code @Component public class SpringmvcConsumerMain { private static final Logger LOG = LoggerFactory.getLogger(SpringmvcConsumerMain.class); public static void main(String[] args) throws Exception { init(); Person person = new Person(); person.setName(\"ServiceComb/Java Chassis\"); //AsyncRestTemplate Consumer CseAsyncRestTemplate cseAsyncRestTemplate = new CseAsyncRestTemplate(); ListenableFuture<ResponseEntity<String>> responseEntityListenableFuture = cseAsyncRestTemplate .postForEntity(\"cse://springmvc/springmvchello/sayhi?name=Java Chassis\", null, String.class); ResponseEntity<String> responseEntity = responseEntityListenableFuture.get(); System.out.println(\"AsyncRestTemplate Consumer sayHi services: \" + responseEntity.getBody()); HttpEntity<Person> entity = new HttpEntity<>(person); ListenableFuture<ResponseEntity<String>> listenableFuture = cseAsyncRestTemplate .exchange(\"cse://springmvc/springmvchello/sayhello\", HttpMethod.POST, entity, String.class); // ResponseEntity<String> responseEntity1 = listenableFuture.get(); // System.out.println(\"AsyncRestTemplate Consumer sayHello services: \" + responseEntity1.getBody()); // Set the callback function listenableFuture.addCallback( new ListenableFutureCallback<ResponseEntity<String>>() { @Override public void onFailure(Throwable ex) { LOG.error(\"AsyncResTemplate Consumer catched exception when sayHello, \", ex); } @Override public void onSuccess(ResponseEntity<String> result) { System.out.println(\"AsyncRestTemplate Consumer sayHello services: \" + result.getBody()); } }); } public static void init() throws Exception { Log4jUtils.init(); BeanUtils.init(); } } Note The URL format is the same with RestTemplate, refer to restTemplate for details The custom ListenableFuture class is the placeholder to get the results from the remote call. Users can also customize the callback function to process the return results in batches.","title":"Using AsyncRestTemplate"},{"location":"build-consumer/using-AsyncRestTemplate/#develop-consumer-with-asyncresttemplate","text":"","title":"Develop consumer with AsyncRestTemplate"},{"location":"build-consumer/using-AsyncRestTemplate/#concepts","text":"AsyncRestTemplate allows users to make asynchronous service calls. The logic is similar to restTemplate, except that the service is called asynchronously.","title":"Concepts"},{"location":"build-consumer/using-AsyncRestTemplate/#sample-code","text":"The AsyncRestTemplate instance is created and retrieved via new CseAsyncRestTemplate() , which is then used to make service calls through a custom URL. Spring MVC client sample code @Component public class SpringmvcConsumerMain { private static final Logger LOG = LoggerFactory.getLogger(SpringmvcConsumerMain.class); public static void main(String[] args) throws Exception { init(); Person person = new Person(); person.setName(\"ServiceComb/Java Chassis\"); //AsyncRestTemplate Consumer CseAsyncRestTemplate cseAsyncRestTemplate = new CseAsyncRestTemplate(); ListenableFuture<ResponseEntity<String>> responseEntityListenableFuture = cseAsyncRestTemplate .postForEntity(\"cse://springmvc/springmvchello/sayhi?name=Java Chassis\", null, String.class); ResponseEntity<String> responseEntity = responseEntityListenableFuture.get(); System.out.println(\"AsyncRestTemplate Consumer sayHi services: \" + responseEntity.getBody()); HttpEntity<Person> entity = new HttpEntity<>(person); ListenableFuture<ResponseEntity<String>> listenableFuture = cseAsyncRestTemplate .exchange(\"cse://springmvc/springmvchello/sayhello\", HttpMethod.POST, entity, String.class); // ResponseEntity<String> responseEntity1 = listenableFuture.get(); // System.out.println(\"AsyncRestTemplate Consumer sayHello services: \" + responseEntity1.getBody()); // Set the callback function listenableFuture.addCallback( new ListenableFutureCallback<ResponseEntity<String>>() { @Override public void onFailure(Throwable ex) { LOG.error(\"AsyncResTemplate Consumer catched exception when sayHello, \", ex); } @Override public void onSuccess(ResponseEntity<String> result) { System.out.println(\"AsyncRestTemplate Consumer sayHello services: \" + result.getBody()); } }); } public static void init() throws Exception { Log4jUtils.init(); BeanUtils.init(); } } Note The URL format is the same with RestTemplate, refer to restTemplate for details The custom ListenableFuture class is the placeholder to get the results from the remote call. Users can also customize the callback function to process the return results in batches.","title":"Sample code"},{"location":"build-consumer/using-resttemplate/","text":"Develop consumer with Rest Template Concepts Rest Template is a RESTful API provided by the Spring framework. ServiceComb provides the implementation class for service calling Scenario With ServiceComb's RestTemplate instance, users can call the service with a customized URL without knowing the service's address. Sample Code The RestTemplate instance is created by the static method RestTemplateBuilder.create() . Then, users can call the microservices with the instance and the customized URL. The code is as follows: Sample code for Sprint MVC consumer import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; import org.apache.servicecomb.foundation.common.utils.BeanUtils; import org.apache.servicecomb.foundation.common.utils.Log4jUtils; import org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder; import org.apache.servicecomb.samples.common.schema.models.Person; @Component public class SpringmvcConsumerMain { private static RestTemplate restTemplate = RestTemplateBuilder.create(); public static void main(String[] args) throws Exception { init(); Person person = new Person(); person.setName(\"ServiceComb/Java Chassis\"); String sayHiResult = restTemplate .postForObject(\"cse://springmvc/springmvchello/sayhi?name=Java Chassis\", null, String.class); String sayHelloResult = restTemplate .postForObject(\"cse://springmvc/springmvchello/sayhello\", person, String.class); System.out.println(\"RestTemplate consumer sayhi services: \" + sayHiResult); System.out.println(\"RestTemplate consumer sayhello services: \" + sayHelloResult); } public static void init() throws Exception { Log4jUtils.init(); BeanUtils.init(); } } Sample code for JAX RS Consumer: @Component public class JaxrsConsumerMain { public static void main(String[] args) throws Exception { init(); // The rest is just like the Spring MVC Consumer sample code, notice that if the provider only accepts GET requests, the consumer should use method getForObject() RestTemplate restTemplate = RestTemplateBuilder.create(); String result = restTemplate.getForObject(\"cse://jaxrs/jaxrshello/saybye\", String.class); } public static void init() throws Exception { Log4jUtils.init(); BeanUtils.init(); } } NOTE: The URL should be in format: cse//microserviceName/path?querystring . Taking the provider example from Develop micro service with SpringMVC , the micro service's name is springmvc , the basePath is /springmvchello , then the microserviceName in the URL is springmvc , the path to call sayhi is springmvchello/sayhi , so the URL for sayhi in the sample is cse://springmvc/springmvchello/sayhi?name=Java Chassis , below is the code for the provider: @RestSchema(schemaId = \"springmvcHello\") @RequestMapping(path = \"/springmvchello\", produces = MediaType.APPLICATION_JSON) //\u8fd9\u91cc path = \u201c/springmvchello\u201d \u4e2d\u7684 springmvchello \u5c31\u662f \u4e0a\u8ff0\u7684basePath public class SpringmvcHelloImpl implements Hello { @Override @RequestMapping(path = \"/sayhi\", method = RequestMethod.POST) public String sayHi(@RequestParam(name = \"name\") String name) { return \"Hello \" + name; } @Override @RequestMapping(path = \"/sayhello\", method = RequestMethod.POST) public String sayHello(@RequestBody Person person) { return \"Hello person \" + person.getName(); } } The following configuration is the file resources/microservice.yaml of the springmvc-provider module in the SpringMVC sample : APPLICATION_ID: springmvc-sample service_description: name: springmvc # The name of the micro service version: 0.0.2 servicecomb: service: registry: address: http://127.0.0.1:30100 rest: address: 0.0.0.0:8080 highway: address: 0.0.0.0:7070 handler: chain: Provider: default: bizkeeper-provider cse: service: registry: address: http://127.0.0.1:30100 #service center address With the URL format, ServiceComb framework will perform internal microservice descovery, fallback, fault tolerance and send the requests to the microservice providers.","title":"Using Rest Template"},{"location":"build-consumer/using-resttemplate/#develop-consumer-with-rest-template","text":"","title":"Develop consumer with Rest Template"},{"location":"build-consumer/using-resttemplate/#concepts","text":"Rest Template is a RESTful API provided by the Spring framework. ServiceComb provides the implementation class for service calling","title":"Concepts"},{"location":"build-consumer/using-resttemplate/#scenario","text":"With ServiceComb's RestTemplate instance, users can call the service with a customized URL without knowing the service's address.","title":"Scenario"},{"location":"build-consumer/using-resttemplate/#sample-code","text":"The RestTemplate instance is created by the static method RestTemplateBuilder.create() . Then, users can call the microservices with the instance and the customized URL. The code is as follows: Sample code for Sprint MVC consumer import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; import org.apache.servicecomb.foundation.common.utils.BeanUtils; import org.apache.servicecomb.foundation.common.utils.Log4jUtils; import org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder; import org.apache.servicecomb.samples.common.schema.models.Person; @Component public class SpringmvcConsumerMain { private static RestTemplate restTemplate = RestTemplateBuilder.create(); public static void main(String[] args) throws Exception { init(); Person person = new Person(); person.setName(\"ServiceComb/Java Chassis\"); String sayHiResult = restTemplate .postForObject(\"cse://springmvc/springmvchello/sayhi?name=Java Chassis\", null, String.class); String sayHelloResult = restTemplate .postForObject(\"cse://springmvc/springmvchello/sayhello\", person, String.class); System.out.println(\"RestTemplate consumer sayhi services: \" + sayHiResult); System.out.println(\"RestTemplate consumer sayhello services: \" + sayHelloResult); } public static void init() throws Exception { Log4jUtils.init(); BeanUtils.init(); } } Sample code for JAX RS Consumer: @Component public class JaxrsConsumerMain { public static void main(String[] args) throws Exception { init(); // The rest is just like the Spring MVC Consumer sample code, notice that if the provider only accepts GET requests, the consumer should use method getForObject() RestTemplate restTemplate = RestTemplateBuilder.create(); String result = restTemplate.getForObject(\"cse://jaxrs/jaxrshello/saybye\", String.class); } public static void init() throws Exception { Log4jUtils.init(); BeanUtils.init(); } } NOTE: The URL should be in format: cse//microserviceName/path?querystring . Taking the provider example from Develop micro service with SpringMVC , the micro service's name is springmvc , the basePath is /springmvchello , then the microserviceName in the URL is springmvc , the path to call sayhi is springmvchello/sayhi , so the URL for sayhi in the sample is cse://springmvc/springmvchello/sayhi?name=Java Chassis , below is the code for the provider: @RestSchema(schemaId = \"springmvcHello\") @RequestMapping(path = \"/springmvchello\", produces = MediaType.APPLICATION_JSON) //\u8fd9\u91cc path = \u201c/springmvchello\u201d \u4e2d\u7684 springmvchello \u5c31\u662f \u4e0a\u8ff0\u7684basePath public class SpringmvcHelloImpl implements Hello { @Override @RequestMapping(path = \"/sayhi\", method = RequestMethod.POST) public String sayHi(@RequestParam(name = \"name\") String name) { return \"Hello \" + name; } @Override @RequestMapping(path = \"/sayhello\", method = RequestMethod.POST) public String sayHello(@RequestBody Person person) { return \"Hello person \" + person.getName(); } } The following configuration is the file resources/microservice.yaml of the springmvc-provider module in the SpringMVC sample : APPLICATION_ID: springmvc-sample service_description: name: springmvc # The name of the micro service version: 0.0.2 servicecomb: service: registry: address: http://127.0.0.1:30100 rest: address: 0.0.0.0:8080 highway: address: 0.0.0.0:7070 handler: chain: Provider: default: bizkeeper-provider cse: service: registry: address: http://127.0.0.1:30100 #service center address With the URL format, ServiceComb framework will perform internal microservice descovery, fallback, fault tolerance and send the requests to the microservice providers.","title":"Sample Code"},{"location":"build-consumer/with-contract/","text":"Using Contracts Scenario When a consumer calls a service from a provider, the contract is required. The consumer can get the providers' contracts in 2 ways: get the providers' contract from off-line, then manually configure it in the project. Or, download the contract from the service center. Configuration NOTE Users can get the contract in either way, regardless of the consumers' development mode. Configure the Dependencies In the microservice.yaml file, configure a provider for the consumer. The following is an example of the configuration: servicecomb: # other configurations omitted references: springmvc: version-rule: 0.0.1 The version-rule field is the rules to match the version, there are 4 version-rule formats: Accurate version: such as version-rule: 0.0.1 , it indicates that only those providers with version 0.0.1 are matched. Later versions: such as version-rule: 1.0.0+ , it indicates that those providers with version greater than 1.0.0 are matched. Latest version: version-rule: latest , it indicates that only those providers with the latest are matched. Version range: such as 1.0.0-2.0.2 , it indicates that those provider with versions between 1.0.0 and 2.0.2 are matched, including 1.0.0 and 2.0.2 The default version matching rule is latest . Manually Configure Contracts When providers' contracts are obtained from off-line, they should be put into the specific directory of the consumer project. The directory is the one mentioned in the configuration description Service Contract . Each directory under the microservices directory indicates a microservice, and each yaml file under the microservice directory represents a contract schema. The file name is the schemaId. The contracts stored in application folder should specify the appId for cross application access. The directory tree is as follows: resources - microservices - serviceName # Microservice name - schemaId.yaml # The contract schemaId - applications - appId # Application ID - serviceName # Microservice name - schemaId.yaml # The contract schemaId Automatically Download Contract from Service Center If a consumer does not explicitly store the contract in the project, when the application starts, ServiceComb framework automatically downloads contracts from the service center based on the providers' microservices name and version configured in microservice.yaml.","title":"Contract"},{"location":"build-consumer/with-contract/#using-contracts","text":"","title":"Using Contracts"},{"location":"build-consumer/with-contract/#scenario","text":"When a consumer calls a service from a provider, the contract is required. The consumer can get the providers' contracts in 2 ways: get the providers' contract from off-line, then manually configure it in the project. Or, download the contract from the service center.","title":"Scenario"},{"location":"build-consumer/with-contract/#configuration","text":"NOTE Users can get the contract in either way, regardless of the consumers' development mode.","title":"Configuration"},{"location":"build-consumer/with-contract/#configure-the-dependencies","text":"In the microservice.yaml file, configure a provider for the consumer. The following is an example of the configuration: servicecomb: # other configurations omitted references: springmvc: version-rule: 0.0.1 The version-rule field is the rules to match the version, there are 4 version-rule formats: Accurate version: such as version-rule: 0.0.1 , it indicates that only those providers with version 0.0.1 are matched. Later versions: such as version-rule: 1.0.0+ , it indicates that those providers with version greater than 1.0.0 are matched. Latest version: version-rule: latest , it indicates that only those providers with the latest are matched. Version range: such as 1.0.0-2.0.2 , it indicates that those provider with versions between 1.0.0 and 2.0.2 are matched, including 1.0.0 and 2.0.2 The default version matching rule is latest .","title":"Configure the Dependencies"},{"location":"build-consumer/with-contract/#manually-configure-contracts","text":"When providers' contracts are obtained from off-line, they should be put into the specific directory of the consumer project. The directory is the one mentioned in the configuration description Service Contract . Each directory under the microservices directory indicates a microservice, and each yaml file under the microservice directory represents a contract schema. The file name is the schemaId. The contracts stored in application folder should specify the appId for cross application access. The directory tree is as follows: resources - microservices - serviceName # Microservice name - schemaId.yaml # The contract schemaId - applications - appId # Application ID - serviceName # Microservice name - schemaId.yaml # The contract schemaId","title":"Manually Configure Contracts"},{"location":"build-consumer/with-contract/#automatically-download-contract-from-service-center","text":"If a consumer does not explicitly store the contract in the project, when the application starts, ServiceComb framework automatically downloads contracts from the service center based on the providers' microservices name and version configured in microservice.yaml.","title":"Automatically Download Contract from Service Center"},{"location":"build-provider/access-log-configuration/","text":"Concepts ServiceComb provides Vert.x based access log. When developing with REST over Vert.x , access log printing can be enabled through a simple configuration. Scenario The user may need the access log when debugging the application. When using REST over servlet, the web container provides the access log function; for REST over Vert.x, ServiceComb provides a set of access log functionalities. Configuration Enable Access Log Add the following configurations in the microservice.yaml file to enable access log: servicecomb: accesslog: enabled: true ## Enable access log Access log Configuration Items Configuration Item Values Default Value Description servicecomb.accesslog.enabled true/false false true to enabled access log servicecomb.accesslog.pattern the format of the log \"%h - - %t %r %s %B\" See log configuration items for more details Note The 2 items are optional, if not configured, the default value will be applied. Log format configuration The currently available configuration items for log are describe in the following table Log configuration items(Apache & W3C) and Log configuration items(ServiceComb) \u3002 Log configuration items (Apache & W3C) Item Apache log format W3C log format Description HTTP method %m cs-method - HTTP status %s sc-status - Duration in second %T - - Duration in millisecond %D - - Remote hostname %h - - Local hostname %v - - Local port %p - - Size of response %B - Print \"0\" if body size is 0 Size of response %b - Print \"-\" if body size is 0 First line of request %r - Include HTTP Method, Uri and HTTP version URI path %U cs-uri-stem - Query string %q cs-uri-query - URI path and query string - cs-uri - Request protocol %H - - Datetime the request is received %t - Print time stamp by the default configuration, the format is \"EEE, dd MMM yyyy HH:mm:ss zzz\", in English and GMT time zone Configurable datetime the request is received %{PATTERN}t - Print time stamp by specified format, in English and GMT time zone Configurable datetime the request is received %{PATTERN|TIMEZONE|LOCALE}t - Print time stamp by the specified format, language and time zone. The items between vertical bar can be empty(while the | should not be omitted) Request header %{VARNAME}i - Print \"-\" if the specified request header is not found Response header %{VARNAME}o - Print \"-\" if the specified response header is not found Cookie %{VARNAME}C - Print \"-\" if the specified cookie is not found Log configuration items(ServiceComb) Element Placeholder Comment TraceId %SCB-traceId Print the trace id generated by ServiceComb, if the id is not found, print \"-\" Invocation Context %{VARNAME}SCB-ctx Print the invocation context value whose key is VARNAME , if the key is not found, print \"-\" Output file configuration The default log framework for Access log is Log4j which provides a default set of configurations for output files. Users can override these configurations in their own log4j.properties file. The configuration items for output files are as follows. Log file configuration items Item Default Value Description Remarks paas.logs.accesslog.dir ${paas.logs.dir} The output path of the log file The common logs will be outputted to the same path paas.logs.accesslog.file access.log Name of the log file - log4j.appender.access.MaxBackupIndex 10 Max file numbers for log rotating - log4j.appender.access.MaxFileSize 20MB Max size of log file When log file reaches the max size, log rotating is triggered .appender.access.logPermission rw------- Log file permissions - Note Since ServiceComb's log function relies only on the slf4j interface, users can select other log frameworks. For other frameworks, users need to configure the log file output options. Switch to logback For the project that uses logback, the log framework dependency should be changed from Log4j to logback with some extra configurations to make access log work. 1. Remove Log4j dependencies Before switching to logback, check the dependencies of the project and remove Log4j related dependencies. Run the maven command dependency:tree in the project, find the ServiceComb components that depend on Log4j, and add the following configuration to its <dependency> : <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> 2. Add a logback dependency Add a dependency for the logback in the pom file: <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> </dependency> 3. Configure the logger for the access log component Since the log component provided by ServiceComb obtains the logger named accesslog for log printing, the key to log framework switching is to provide a file called accesslog and configure the output file for it. The following is a sample configuration of the access log for logback. It only shows the configurations related to the access log. Other log configurations are omitted: <?xml version=\"1.0\" encoding=\"UTF-8\"?> <configuration> <!-- Users can customize the appender by their requirement --> <appender name=\"ACCESSLOG\" class=\"ch.qos.logback.core.rolling.RollingFileAppender\"> <file>./logs/access.log</file> <rollingPolicy class=\"ch.qos.logback.core.rolling.TimeBasedRollingPolicy\"> <fileNamePattern>./logs/access-%d{yyyy-MM-dd}.log</fileNamePattern> </rollingPolicy> <!-- Note: the access log content is formatted in code, the pattern should only specify the message without extra format --> <encoder> <pattern>%msg%n</pattern> </encoder> </appender> <!-- Provide a logger named \"accesslog\" for log printing --> <logger name=\"accesslog\" level=\"INFO\" additivity=\"false\"> <appender-ref ref=\"ACCESSLOG\" /> </logger> </configuration> Extending Access Log Users can customize their AccessLogItem by ServiceComb's AccessLogItem extension mechanism. Related classes AccessLogItem public interface AccessLogItem<T> { /** * Get specified content from accessLogParam, generate the access log and return */ String getFormattedItem(AccessLogParam<T> accessLogParam); } The definition of AccessLogItem is as shown above. When request triggers Access Log printing, ServiceComb's Access Log mechanism will traverse a valid AccessLogItem , call the getFormattedItem method to get the item's Access Log fragment, concatenate all the the fragments into an Access Log, and output it to the log file. The parameter AccessLogParam<T> contains the request start time, the end time, and the request context of type T . In the REST over Vert.x communication mode, the type T is the RoutingContext of Vert.x. VertxRestAccessLogItemMeta // pattern placeholder prefix protected String prefix; // pattern placeholder suffix protected String suffix; // order number of priority protected int order; // AccessLogItem constructor protected AccessLogItemCreator<RoutingContext> accessLogItemCreator; The VertxRestAccessLogItemMeta contains the properties listed above, it specifies how ServiceComb parse the pattern string to get specific AccessLogItem. To define a AccessLogItem with placeholder %user-defined , declare a subclass of VertxRestAccessLogItemMeta \uff0cset prefix=\"%user-defined\", suffix=null, when AccessLogPatternParser parses the \"%user-defined\", it will fetch the AccessLogItemCreator from the meta class and create the corresponding AccessLogItem . Note: since there is not variable in placeholder \"%user-defined\", the call to AccessLogItemCreator passes the configuration parameter null\u3002 To get a AccessLogItem with placeholder %{VARNAME}user-defined , declare a subclass of VertxRestAccessLogItemMeta , set prefix=\"%{\", suffix=\"}user-defined\". When AccessLogPatternParser parses \"%{VARNAME}user-defined\", it will extract the \"VARNAME\" as parameter to call AccessLogItemCreator , to create a AccessLogItem . VertxRestAccessLogItemMeta has a subclass CompositeVertxRestAccessLogItemMeta . When user needs to define multiple AccessLogItems, multiple VertxRestAccessLogItemMeta can be aggregated into CompositeVertxRestAccessLogItemMeta . When Parser loads AccessLogItemMeta of type CompositeVertxRestAccessLogItemMeta , it calls the meta class's getAccessLogItemMetas() method to get a set of AccessLogItemMeta. VertxRestAccessLogItemMeta is loaded by the SPI mechanism, and CompositeVertxRestAccessLogItemMeta allows user to load multiple meta infos with on one record in the SPI configuration file, which provides great flexibility. AccessLogItemCreator public interface AccessLogItemCreator<T> { // Receive configuration values and return an AccessLogItem. The method receives a null if there is no variables in AccessLogItem placeholder AccessLogItem<T> createItem(String config); } The user instantiates his AccessLogItem by setting the AccessLogItemCreator in the custom VertxRestAccessLogItemMeta. Since this is a functional interface, when the AccessLogItem is initialized in a simple way, you can directly define the Creator using a Lambda expression to simplify development. Matching rules of AccessLogItemMeta Once AccessLogItemMeta is loaded into the Parser, it will be sorted once. Parser will match the meta list from front to back when parsing the pattern string. The general matching rules are as follows: 1. Match metas with higher priority. 2. Match the meta with suffix first. When metas with multiple suffixes are matched, ~~take the one with the smallest suffix.~~ 3. Match the meta with a longer placeholder, for example, there are two metas, \"%abc\" and \"%a\". If \"%abc\" is matched, it will return directly. Sample Extend AccessLogItem First, the user needs the AccessLogItem interface to implement their own item: public class UserDefinedAccessLogItem implements AccessLogItem<RoutingContext> { private String config; public UserDefinedAccessLogItem(String config) { this.config = config; } @Override public String getFormattedItem(AccessLogParam<RoutingContext> accessLogParam) { // Here is the user's custom logic, user needs to take relevant data from AccessLogParam or other places, generate and return access log fragments return \"user-defined-[\" + config + \"]-[\" + accessLogParam.getStartMillisecond() + \"]\"; } } Define AccessLogItem meta class Inherit the class VertxRestAccessLogItemMeta or CompositeVertxRestAccessLogItemMeta , define the prefix and suffix of the AccessLogItem: public class UserDefinedCompositeExtendedAccessLogItemMeta extends CompositeVertxRestAccessLogItemMeta { private static final List<VertxRestAccessLogItemMeta> META_LIST = new ArrayList<>(); static { META_LIST.add(new VertxRestAccessLogItemMeta(\"%{\", \"}user-defined\", UserDefinedAccessLogItem::new)); } @Override public List<VertxRestAccessLogItemMeta> getAccessLogItemMetas() { return META_LIST; } } Configure the SPI load file In the resources/META-INF/services/ directory, create a file named \"org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemMeta\" and fill in the full class path of the meta class defined in the previous step. Parser will use this file to load the meta class. Configure Access Log pattern The configuration pattern in the microservice.yaml file is assumed to be \"%{test-config}user-defined\". The running service triggers the Access Log to print. If the request start time is 1, Access Log will print \"user- Defined-[test-config]-[1]\". Sample code Configurations in microservice.yaml ## other configurations omitted servicecomb: accesslog: enabled: true ## Enable access log pattern: \"%h - - %t %r %s %B\" ## Custom log format Configurations in log4j.properties # access log configuration item paas.logs.accesslog.dir=../logs/ paas.logs.accesslog.file=access.log # access log File appender log4j.appender.access.MaxBackupIndex=10 log4j.appender.access.MaxFileSize=20MB log4j.appender.access.logPermission=rw-------","title":"Access Log Configuration"},{"location":"build-provider/access-log-configuration/#concepts","text":"ServiceComb provides Vert.x based access log. When developing with REST over Vert.x , access log printing can be enabled through a simple configuration.","title":"Concepts"},{"location":"build-provider/access-log-configuration/#scenario","text":"The user may need the access log when debugging the application. When using REST over servlet, the web container provides the access log function; for REST over Vert.x, ServiceComb provides a set of access log functionalities.","title":"Scenario"},{"location":"build-provider/access-log-configuration/#configuration","text":"","title":"Configuration"},{"location":"build-provider/access-log-configuration/#enable-access-log","text":"Add the following configurations in the microservice.yaml file to enable access log: servicecomb: accesslog: enabled: true ## Enable access log Access log Configuration Items Configuration Item Values Default Value Description servicecomb.accesslog.enabled true/false false true to enabled access log servicecomb.accesslog.pattern the format of the log \"%h - - %t %r %s %B\" See log configuration items for more details Note The 2 items are optional, if not configured, the default value will be applied.","title":"Enable Access Log"},{"location":"build-provider/access-log-configuration/#log-format-configuration","text":"The currently available configuration items for log are describe in the following table Log configuration items(Apache & W3C) and Log configuration items(ServiceComb) \u3002 Log configuration items (Apache & W3C) Item Apache log format W3C log format Description HTTP method %m cs-method - HTTP status %s sc-status - Duration in second %T - - Duration in millisecond %D - - Remote hostname %h - - Local hostname %v - - Local port %p - - Size of response %B - Print \"0\" if body size is 0 Size of response %b - Print \"-\" if body size is 0 First line of request %r - Include HTTP Method, Uri and HTTP version URI path %U cs-uri-stem - Query string %q cs-uri-query - URI path and query string - cs-uri - Request protocol %H - - Datetime the request is received %t - Print time stamp by the default configuration, the format is \"EEE, dd MMM yyyy HH:mm:ss zzz\", in English and GMT time zone Configurable datetime the request is received %{PATTERN}t - Print time stamp by specified format, in English and GMT time zone Configurable datetime the request is received %{PATTERN|TIMEZONE|LOCALE}t - Print time stamp by the specified format, language and time zone. The items between vertical bar can be empty(while the | should not be omitted) Request header %{VARNAME}i - Print \"-\" if the specified request header is not found Response header %{VARNAME}o - Print \"-\" if the specified response header is not found Cookie %{VARNAME}C - Print \"-\" if the specified cookie is not found Log configuration items(ServiceComb) Element Placeholder Comment TraceId %SCB-traceId Print the trace id generated by ServiceComb, if the id is not found, print \"-\" Invocation Context %{VARNAME}SCB-ctx Print the invocation context value whose key is VARNAME , if the key is not found, print \"-\"","title":"Log format configuration"},{"location":"build-provider/access-log-configuration/#output-file-configuration","text":"The default log framework for Access log is Log4j which provides a default set of configurations for output files. Users can override these configurations in their own log4j.properties file. The configuration items for output files are as follows. Log file configuration items Item Default Value Description Remarks paas.logs.accesslog.dir ${paas.logs.dir} The output path of the log file The common logs will be outputted to the same path paas.logs.accesslog.file access.log Name of the log file - log4j.appender.access.MaxBackupIndex 10 Max file numbers for log rotating - log4j.appender.access.MaxFileSize 20MB Max size of log file When log file reaches the max size, log rotating is triggered .appender.access.logPermission rw------- Log file permissions - Note Since ServiceComb's log function relies only on the slf4j interface, users can select other log frameworks. For other frameworks, users need to configure the log file output options.","title":"Output file configuration"},{"location":"build-provider/access-log-configuration/#switch-to-logback","text":"For the project that uses logback, the log framework dependency should be changed from Log4j to logback with some extra configurations to make access log work.","title":"Switch to logback"},{"location":"build-provider/access-log-configuration/#1-remove-log4j-dependencies","text":"Before switching to logback, check the dependencies of the project and remove Log4j related dependencies. Run the maven command dependency:tree in the project, find the ServiceComb components that depend on Log4j, and add the following configuration to its <dependency> : <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion>","title":"1. Remove Log4j dependencies"},{"location":"build-provider/access-log-configuration/#2-add-a-logback-dependency","text":"Add a dependency for the logback in the pom file: <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> </dependency>","title":"2. Add a logback dependency"},{"location":"build-provider/access-log-configuration/#3-configure-the-logger-for-the-access-log-component","text":"Since the log component provided by ServiceComb obtains the logger named accesslog for log printing, the key to log framework switching is to provide a file called accesslog and configure the output file for it. The following is a sample configuration of the access log for logback. It only shows the configurations related to the access log. Other log configurations are omitted: <?xml version=\"1.0\" encoding=\"UTF-8\"?> <configuration> <!-- Users can customize the appender by their requirement --> <appender name=\"ACCESSLOG\" class=\"ch.qos.logback.core.rolling.RollingFileAppender\"> <file>./logs/access.log</file> <rollingPolicy class=\"ch.qos.logback.core.rolling.TimeBasedRollingPolicy\"> <fileNamePattern>./logs/access-%d{yyyy-MM-dd}.log</fileNamePattern> </rollingPolicy> <!-- Note: the access log content is formatted in code, the pattern should only specify the message without extra format --> <encoder> <pattern>%msg%n</pattern> </encoder> </appender> <!-- Provide a logger named \"accesslog\" for log printing --> <logger name=\"accesslog\" level=\"INFO\" additivity=\"false\"> <appender-ref ref=\"ACCESSLOG\" /> </logger> </configuration>","title":"3. Configure the logger for the access log component"},{"location":"build-provider/access-log-configuration/#extending-access-log","text":"Users can customize their AccessLogItem by ServiceComb's AccessLogItem extension mechanism.","title":"Extending Access Log"},{"location":"build-provider/access-log-configuration/#related-classes","text":"AccessLogItem public interface AccessLogItem<T> { /** * Get specified content from accessLogParam, generate the access log and return */ String getFormattedItem(AccessLogParam<T> accessLogParam); } The definition of AccessLogItem is as shown above. When request triggers Access Log printing, ServiceComb's Access Log mechanism will traverse a valid AccessLogItem , call the getFormattedItem method to get the item's Access Log fragment, concatenate all the the fragments into an Access Log, and output it to the log file. The parameter AccessLogParam<T> contains the request start time, the end time, and the request context of type T . In the REST over Vert.x communication mode, the type T is the RoutingContext of Vert.x. VertxRestAccessLogItemMeta // pattern placeholder prefix protected String prefix; // pattern placeholder suffix protected String suffix; // order number of priority protected int order; // AccessLogItem constructor protected AccessLogItemCreator<RoutingContext> accessLogItemCreator; The VertxRestAccessLogItemMeta contains the properties listed above, it specifies how ServiceComb parse the pattern string to get specific AccessLogItem. To define a AccessLogItem with placeholder %user-defined , declare a subclass of VertxRestAccessLogItemMeta \uff0cset prefix=\"%user-defined\", suffix=null, when AccessLogPatternParser parses the \"%user-defined\", it will fetch the AccessLogItemCreator from the meta class and create the corresponding AccessLogItem . Note: since there is not variable in placeholder \"%user-defined\", the call to AccessLogItemCreator passes the configuration parameter null\u3002 To get a AccessLogItem with placeholder %{VARNAME}user-defined , declare a subclass of VertxRestAccessLogItemMeta , set prefix=\"%{\", suffix=\"}user-defined\". When AccessLogPatternParser parses \"%{VARNAME}user-defined\", it will extract the \"VARNAME\" as parameter to call AccessLogItemCreator , to create a AccessLogItem . VertxRestAccessLogItemMeta has a subclass CompositeVertxRestAccessLogItemMeta . When user needs to define multiple AccessLogItems, multiple VertxRestAccessLogItemMeta can be aggregated into CompositeVertxRestAccessLogItemMeta . When Parser loads AccessLogItemMeta of type CompositeVertxRestAccessLogItemMeta , it calls the meta class's getAccessLogItemMetas() method to get a set of AccessLogItemMeta. VertxRestAccessLogItemMeta is loaded by the SPI mechanism, and CompositeVertxRestAccessLogItemMeta allows user to load multiple meta infos with on one record in the SPI configuration file, which provides great flexibility. AccessLogItemCreator public interface AccessLogItemCreator<T> { // Receive configuration values and return an AccessLogItem. The method receives a null if there is no variables in AccessLogItem placeholder AccessLogItem<T> createItem(String config); } The user instantiates his AccessLogItem by setting the AccessLogItemCreator in the custom VertxRestAccessLogItemMeta. Since this is a functional interface, when the AccessLogItem is initialized in a simple way, you can directly define the Creator using a Lambda expression to simplify development.","title":"Related classes"},{"location":"build-provider/access-log-configuration/#matching-rules-of-accesslogitemmeta","text":"Once AccessLogItemMeta is loaded into the Parser, it will be sorted once. Parser will match the meta list from front to back when parsing the pattern string. The general matching rules are as follows: 1. Match metas with higher priority. 2. Match the meta with suffix first. When metas with multiple suffixes are matched, ~~take the one with the smallest suffix.~~ 3. Match the meta with a longer placeholder, for example, there are two metas, \"%abc\" and \"%a\". If \"%abc\" is matched, it will return directly.","title":"Matching rules of AccessLogItemMeta"},{"location":"build-provider/access-log-configuration/#sample","text":"Extend AccessLogItem First, the user needs the AccessLogItem interface to implement their own item: public class UserDefinedAccessLogItem implements AccessLogItem<RoutingContext> { private String config; public UserDefinedAccessLogItem(String config) { this.config = config; } @Override public String getFormattedItem(AccessLogParam<RoutingContext> accessLogParam) { // Here is the user's custom logic, user needs to take relevant data from AccessLogParam or other places, generate and return access log fragments return \"user-defined-[\" + config + \"]-[\" + accessLogParam.getStartMillisecond() + \"]\"; } } Define AccessLogItem meta class Inherit the class VertxRestAccessLogItemMeta or CompositeVertxRestAccessLogItemMeta , define the prefix and suffix of the AccessLogItem: public class UserDefinedCompositeExtendedAccessLogItemMeta extends CompositeVertxRestAccessLogItemMeta { private static final List<VertxRestAccessLogItemMeta> META_LIST = new ArrayList<>(); static { META_LIST.add(new VertxRestAccessLogItemMeta(\"%{\", \"}user-defined\", UserDefinedAccessLogItem::new)); } @Override public List<VertxRestAccessLogItemMeta> getAccessLogItemMetas() { return META_LIST; } } Configure the SPI load file In the resources/META-INF/services/ directory, create a file named \"org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemMeta\" and fill in the full class path of the meta class defined in the previous step. Parser will use this file to load the meta class. Configure Access Log pattern The configuration pattern in the microservice.yaml file is assumed to be \"%{test-config}user-defined\". The running service triggers the Access Log to print. If the request start time is 1, Access Log will print \"user- Defined-[test-config]-[1]\".","title":"Sample"},{"location":"build-provider/access-log-configuration/#sample-code","text":"","title":"Sample code"},{"location":"build-provider/access-log-configuration/#configurations-in-microserviceyaml","text":"## other configurations omitted servicecomb: accesslog: enabled: true ## Enable access log pattern: \"%h - - %t %r %s %B\" ## Custom log format","title":"Configurations in microservice.yaml"},{"location":"build-provider/access-log-configuration/#configurations-in-log4jproperties","text":"# access log configuration item paas.logs.accesslog.dir=../logs/ paas.logs.accesslog.file=access.log # access log File appender log4j.appender.access.MaxBackupIndex=10 log4j.appender.access.MaxFileSize=20MB log4j.appender.access.logPermission=rw-------","title":"Configurations in log4j.properties"},{"location":"build-provider/bootup/","text":"Application Boot-up Process Concepts The startup process of a service provider includes initializing Log4j, loading bean(including its parameters), and registering service. Initialize Log4j: By default, Log4jUtils merges the log4j configurations from classpath\\*:config/base/log4j.properties and classpath\\*:config/log4j.properties , then transfer them to log4j's PropertyConfigurator method to initialize it. If the configuration file with the highest priority is stored on the disk directory with write permission, the combined configuration will be saved to this location to view which parameters take effect during maintenance. Load the bean. By default BeanUtils loads the configuration file from the classpath\\*:META-INF/spring/\\*.bean.xml and transfer the configuration to ClassPathXmlApplicationContext of the Spring framework to load the application context. The bean of foundation-config module will be loaded during the process. Register the service. When Spring context is loaded, org.apache.servicecomb.core.CseApplicationListener will load the handlers configurations and providers' schema info, then register the microservice in the Service Center. NOTE: ServiceComb has 3 configuration sources: configuration center, environment variables and local files, with priorities from high to low. If there are configuration items with the same name in different sources, then items with lower priority will be overwritten. Configuration items stored in the configuration center can be modified at runtime.","title":"Boot-up Process"},{"location":"build-provider/bootup/#application-boot-up-process","text":"","title":"Application Boot-up Process"},{"location":"build-provider/bootup/#concepts","text":"The startup process of a service provider includes initializing Log4j, loading bean(including its parameters), and registering service. Initialize Log4j: By default, Log4jUtils merges the log4j configurations from classpath\\*:config/base/log4j.properties and classpath\\*:config/log4j.properties , then transfer them to log4j's PropertyConfigurator method to initialize it. If the configuration file with the highest priority is stored on the disk directory with write permission, the combined configuration will be saved to this location to view which parameters take effect during maintenance. Load the bean. By default BeanUtils loads the configuration file from the classpath\\*:META-INF/spring/\\*.bean.xml and transfer the configuration to ClassPathXmlApplicationContext of the Spring framework to load the application context. The bean of foundation-config module will be loaded during the process. Register the service. When Spring context is loaded, org.apache.servicecomb.core.CseApplicationListener will load the handlers configurations and providers' schema info, then register the microservice in the Service Center. NOTE: ServiceComb has 3 configuration sources: configuration center, environment variables and local files, with priorities from high to low. If there are configuration items with the same name in different sources, then items with lower priority will be overwritten. Configuration items stored in the configuration center can be modified at runtime.","title":"Concepts"},{"location":"build-provider/code-first/","text":"Implicit Contract Concept Description The Implicit Contract definition is ServiceComb automatically generate a contract of service based on the service implementation class. Scenario By using the implicit API definition you can define the implementation class without pre-defining APIs. When the service is started, an API is automatically generated and registered to the service center. Involved API Implicit API definitions can be used for Spring MVC, JAX-RS, and transparent RPC development modes, For details, see Development Style-SpringMVC , Development Stype-JAX-RS and Development Style-Transparent RPC . When you develop a microservice in transparent RPC mode, the code does not show how you want to define an API, and all generated APIs are POST methods, The input parameters of all the methods will be packaged as a class and transferred as body parameters. Therefore, if you develop providers using implicit APIs, you are advised to choose Spring MVC or JAX-RS mode to obtain complete RESTful statements.","title":"Implicit API definition"},{"location":"build-provider/code-first/#implicit-contract","text":"","title":"Implicit Contract"},{"location":"build-provider/code-first/#concept-description","text":"The Implicit Contract definition is ServiceComb automatically generate a contract of service based on the service implementation class.","title":"Concept Description"},{"location":"build-provider/code-first/#scenario","text":"By using the implicit API definition you can define the implementation class without pre-defining APIs. When the service is started, an API is automatically generated and registered to the service center.","title":"Scenario"},{"location":"build-provider/code-first/#involved-api","text":"Implicit API definitions can be used for Spring MVC, JAX-RS, and transparent RPC development modes, For details, see Development Style-SpringMVC , Development Stype-JAX-RS and Development Style-Transparent RPC . When you develop a microservice in transparent RPC mode, the code does not show how you want to define an API, and all generated APIs are POST methods, The input parameters of all the methods will be packaged as a class and transferred as body parameters. Therefore, if you develop providers using implicit APIs, you are advised to choose Spring MVC or JAX-RS mode to obtain complete RESTful statements.","title":"Involved API"},{"location":"build-provider/define-contract/","text":"Service Contract Definition Concept Description The Service Contract refers to the micro-service interface contract based on the OpenAPI specification. The interface definition between the server and the consumer. The java chassis provides two ways to define the contract: 'code first' and 'contract first'. Code first The Producer use of Jax-RS or SpringMVC's RESTful annotation declares the input and output parameters of the interface, or with the OpenAPI annotations, to add human-readable information, such as sample code, text descriptions, etc.; when the ServiceComb engine starts, according to these annotations generate a contract description and automatically upload it to the service center. The producer can also be developed using the transparent RPC model, but since there is no RESTful annotation to guide how to generate the contract, at this time, the automatically generated contract very non-standard and not recommended. The consumer is called with a transparent RPC or RestTemplate. Under the code first development model, developers do not have to handwritten contracts. Contract first In this scenario, instead of using the contract automatically generated by the framework, the contract file provided by the developer is directly used, which requires the developer to ensure the consistency of the contract and the code. Scenario The service contract is used for decoupling between the server and the consumer. The server implements the service around the contract. The consumer invokes the service according to the contract, which can support the server and the consumer to implement in different programming languages. Description: The service provider registers the interface contract with the service center at startup, which can be downloaded and used by the service consumer. The interface contract is micro-service-version level information. When multiple micro-service instances are started, if an instance registers the contract with the service center, the service center will not overwrite the existing contract with the contract information registered by the latecomer. Therefore, only modifying the service provider's interface information will not change the contract stored by the service center. For the service consumer, the acquired interface information is still old. To update the interface contract in the service center, you can choose to upgrade the microservice version number or delete existing microservice information (the latter is not recommended for use in a production environment). Configuration ServiceComb defines API in a .yaml file. It's recommended to use Swagger Editor to define the APIs. This tool can check syntax and automaticlly generate an API document. For details about the API definition file format, see Official OpenAPI documentation \u3002 The API definition file is located in \"resources/microservices\" or \"resources/applications\" directory. The directory structure is as follows: resources - microservices - serviceName #Microservice name - schemaId.yaml #schema ID - applications - appId #Application ID - serviceName #Service name - schemaId.yaml #Schema ID Note : ServiceComb's Swagger contract file should be saved using the UTF-8 character set. If the user saves the contract file with a different character set and the file contains Chinese characters, it may cause an unknown error. Sample Code The contents of the schemaId.yaml file in the resources/microservices directory and the resources/application directory are as follows. The interface definitions in the file need to match the actual interface of the service. swagger: '2.0' info: title: hello version: 1.0.0 x-java-interface: org.apache.servicecomb.samples.common.schema.Hello basePath: /springmvchello produces: - application/json paths: /sayhi: post: operationId: sayHi parameters: - name: name in: query required: true type: string responses: 200: description: return value schema: type: string default: description: return a default result schema: type: string /sayhello: post: operationId: sayHello parameters: - name: person in: body required: true schema: $ref: \"#/definitions/Person\" responses: 200: description: return value schema: type: string default: description: return a default result schema: type: string definitions: Person: type: \"object\" properties: name: type: \"string\" description: \"person name\" xml: name: \"Person\" NOTE \uff1a * Contract in ServiceComb, it is recommended that basePath not include the web root of the web container, and the url pattern of the servlet. Because ServiceComb supports deployment decoupling, it can be deployed independently from the servlet container, or deployed to the servlet container using the war, or it can be run using the embedded servlet container. As long as the base path does not contain the web root and the url pattern, the actual url changes caused by the deployment mode modification, the ServiceComb consumer business code does not need to be perceived, and the framework will automatically adapt. info.x-java-interface needs to indicate the specific interface path, depending on the actual situation of the project. SchemaId can contain \".\" characters, but it is not recommended. This is because the configuration file used by ServiceComb is in yaml format. The \".\" symbol is used to split the configuration item name. If the SchemaId also contains \".\", some configurations that support the contract level may not be recognized correctly. The \".\" character cannot be included in the naming of the OperationId.","title":"Service contract definition"},{"location":"build-provider/define-contract/#service-contract-definition","text":"","title":"Service Contract Definition"},{"location":"build-provider/define-contract/#concept-description","text":"The Service Contract refers to the micro-service interface contract based on the OpenAPI specification. The interface definition between the server and the consumer. The java chassis provides two ways to define the contract: 'code first' and 'contract first'. Code first The Producer use of Jax-RS or SpringMVC's RESTful annotation declares the input and output parameters of the interface, or with the OpenAPI annotations, to add human-readable information, such as sample code, text descriptions, etc.; when the ServiceComb engine starts, according to these annotations generate a contract description and automatically upload it to the service center. The producer can also be developed using the transparent RPC model, but since there is no RESTful annotation to guide how to generate the contract, at this time, the automatically generated contract very non-standard and not recommended. The consumer is called with a transparent RPC or RestTemplate. Under the code first development model, developers do not have to handwritten contracts. Contract first In this scenario, instead of using the contract automatically generated by the framework, the contract file provided by the developer is directly used, which requires the developer to ensure the consistency of the contract and the code.","title":"Concept Description"},{"location":"build-provider/define-contract/#scenario","text":"The service contract is used for decoupling between the server and the consumer. The server implements the service around the contract. The consumer invokes the service according to the contract, which can support the server and the consumer to implement in different programming languages. Description: The service provider registers the interface contract with the service center at startup, which can be downloaded and used by the service consumer. The interface contract is micro-service-version level information. When multiple micro-service instances are started, if an instance registers the contract with the service center, the service center will not overwrite the existing contract with the contract information registered by the latecomer. Therefore, only modifying the service provider's interface information will not change the contract stored by the service center. For the service consumer, the acquired interface information is still old. To update the interface contract in the service center, you can choose to upgrade the microservice version number or delete existing microservice information (the latter is not recommended for use in a production environment).","title":"Scenario"},{"location":"build-provider/define-contract/#configuration","text":"ServiceComb defines API in a .yaml file. It's recommended to use Swagger Editor to define the APIs. This tool can check syntax and automaticlly generate an API document. For details about the API definition file format, see Official OpenAPI documentation \u3002 The API definition file is located in \"resources/microservices\" or \"resources/applications\" directory. The directory structure is as follows: resources - microservices - serviceName #Microservice name - schemaId.yaml #schema ID - applications - appId #Application ID - serviceName #Service name - schemaId.yaml #Schema ID Note : ServiceComb's Swagger contract file should be saved using the UTF-8 character set. If the user saves the contract file with a different character set and the file contains Chinese characters, it may cause an unknown error.","title":"Configuration"},{"location":"build-provider/define-contract/#sample-code","text":"The contents of the schemaId.yaml file in the resources/microservices directory and the resources/application directory are as follows. The interface definitions in the file need to match the actual interface of the service. swagger: '2.0' info: title: hello version: 1.0.0 x-java-interface: org.apache.servicecomb.samples.common.schema.Hello basePath: /springmvchello produces: - application/json paths: /sayhi: post: operationId: sayHi parameters: - name: name in: query required: true type: string responses: 200: description: return value schema: type: string default: description: return a default result schema: type: string /sayhello: post: operationId: sayHello parameters: - name: person in: body required: true schema: $ref: \"#/definitions/Person\" responses: 200: description: return value schema: type: string default: description: return a default result schema: type: string definitions: Person: type: \"object\" properties: name: type: \"string\" description: \"person name\" xml: name: \"Person\" NOTE \uff1a * Contract in ServiceComb, it is recommended that basePath not include the web root of the web container, and the url pattern of the servlet. Because ServiceComb supports deployment decoupling, it can be deployed independently from the servlet container, or deployed to the servlet container using the war, or it can be run using the embedded servlet container. As long as the base path does not contain the web root and the url pattern, the actual url changes caused by the deployment mode modification, the ServiceComb consumer business code does not need to be perceived, and the framework will automatically adapt. info.x-java-interface needs to indicate the specific interface path, depending on the actual situation of the project. SchemaId can contain \".\" characters, but it is not recommended. This is because the configuration file used by ServiceComb is in yaml format. The \".\" symbol is used to split the configuration item name. If the SchemaId also contains \".\", some configurations that support the contract level may not be recognized correctly. The \".\" character cannot be included in the naming of the OperationId.","title":"Sample Code"},{"location":"build-provider/interface-constraints/","text":"API Constraints A Java Chassis API constraints is that an API definition should describe its usage. You can identify how to call the API without checking the code. As developers, we aim at making our APIs easy to be called. However, developers have different understanding about this aim. For example: public Person query(String id); public Object query(String id); public Person query(String name); Obviously, if API 1 is called, we know that an ID parameter of String type needs to be transferred. The returned value is of Person type, which contains a string-typed name parameter. If API 2 is called, we do not know how to process the returned value, and need to refer to documents provided by the service provider. API 2 is developed in the perspective of RPC developers. To release an API as a REST API, we can use the swagger file; specify the ID to be transmitted using RequestParam, PathVariable, or RequestBody; or use the label provided by SpringMVC or JAX-RS. public Person query(@RequestParam String id); public Person query(@PathVariable String id); public Person query(@RequestBody String id); Generally , simple data types, such as String and int, are transmitted in RequestParam or PathVariable, and complex data types are transmitted in RequestBody after being coded using JSON, to reduce problems cause by HTTP protocol restrictions on developers. Detailed Constraint List Developers cannot use the following types to define APIs: Abstract data structures, such as java.lang.Object, net.sf.json.JsonObject API or abstract class java public interface IPerson {...} public abstract class AbstractPerson {...} Generic type java public class PersonHolder<T> {...} A collection type of the preceding types or a set without a specified type, such as List<IPerson>, Map<String, PersonHolder<?>>, List, Map . such as List<String>, List<Person> are supported. java public class GroupOfPerson {IPerson master ...} Developers do not need to worry about the constraints. The program automatically checks them when it is started, and displays types as properties. Protocol Difference Although ServiceComb-Java-Chassis implements transparent transmission between protocols, there are slight differences between protocols due to the limitations of the underlying protocols: Map, The key supports only string. highway (protobuf restriction) Null values cannot be transmitted over the network, including elements in Collection and array, and value in map. The array and list with the length of 0 are not transmitted over the network. The receiver obtains the default value after decoding them. springmvc Date cannot be used for the path or query parameter. Spring MVC stores toString in path and query, which does not match the swagger standard.","title":"Interface definition and data type"},{"location":"build-provider/interface-constraints/#api-constraints","text":"A Java Chassis API constraints is that an API definition should describe its usage. You can identify how to call the API without checking the code. As developers, we aim at making our APIs easy to be called. However, developers have different understanding about this aim. For example: public Person query(String id); public Object query(String id); public Person query(String name); Obviously, if API 1 is called, we know that an ID parameter of String type needs to be transferred. The returned value is of Person type, which contains a string-typed name parameter. If API 2 is called, we do not know how to process the returned value, and need to refer to documents provided by the service provider. API 2 is developed in the perspective of RPC developers. To release an API as a REST API, we can use the swagger file; specify the ID to be transmitted using RequestParam, PathVariable, or RequestBody; or use the label provided by SpringMVC or JAX-RS. public Person query(@RequestParam String id); public Person query(@PathVariable String id); public Person query(@RequestBody String id); Generally , simple data types, such as String and int, are transmitted in RequestParam or PathVariable, and complex data types are transmitted in RequestBody after being coded using JSON, to reduce problems cause by HTTP protocol restrictions on developers.","title":"API Constraints"},{"location":"build-provider/interface-constraints/#detailed-constraint-list","text":"Developers cannot use the following types to define APIs: Abstract data structures, such as java.lang.Object, net.sf.json.JsonObject API or abstract class java public interface IPerson {...} public abstract class AbstractPerson {...} Generic type java public class PersonHolder<T> {...} A collection type of the preceding types or a set without a specified type, such as List<IPerson>, Map<String, PersonHolder<?>>, List, Map . such as List<String>, List<Person> are supported. java public class GroupOfPerson {IPerson master ...} Developers do not need to worry about the constraints. The program automatically checks them when it is started, and displays types as properties.","title":"Detailed Constraint List"},{"location":"build-provider/interface-constraints/#protocol-difference","text":"Although ServiceComb-Java-Chassis implements transparent transmission between protocols, there are slight differences between protocols due to the limitations of the underlying protocols: Map, The key supports only string. highway (protobuf restriction) Null values cannot be transmitted over the network, including elements in Collection and array, and value in map. The array and list with the length of 0 are not transmitted over the network. The receiver obtains the default value after decoding them. springmvc Date cannot be used for the path or query parameter. Spring MVC stores toString in path and query, which does not match the swagger standard.","title":"Protocol Difference"},{"location":"build-provider/jaxrs/","text":"Develop Microservice with JAX-RS Concept Description ServiceComb supports developers in developing services in JAX-RS mode by using JAX-RS. Development Example Step 1 Import dependencies into your maven project: xml <dependencyManagement> <dependencies> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>java-chassis-dependencies</artifactId> <version>1.0.0-m1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!--transport can optional import through endpoint setting in microservice.yaml, we import both rest and highway as example--> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>transport-rest-vertx</artifactId> </dependency> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>transport-highway</artifactId> </dependency> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>provider-jaxrs</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </dependency> </dependencies> Step 2 Implement the service. JAX-RS is used to describe the development of service code. The implementation of the Hello service is as follows: ```java import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import org.apache.servicecomb.samples.common.schema.models.Person; @Path(\"/jaxrshello\") @Produces(MediaType.APPLICATION_JSON) public class JaxrsHelloImpl { @Path(\"/sayhi\") @POST public String sayHi(String name) { \u3000return \"Hello \" + name; } @Path(\"/sayhello\") @POST public String sayHello(Person person) { return \"Hello person \" + person.getName(); } } ``` Note: PLEASE MAKE SURE TO MARK @Path ON YOUR PRODUCER(JaxrsHelloImpl), OR THE PATH AND METHOD OF PUBLISHED WILL BE INCORRECT! In this sample the Path of sayHi is /jaxrshello/sayhi , and the Path of sayHello is /jaxrshello/sayhello , if you wish them /sayhi and /sayhello , please change the setting of @Path on the JaxrsHelloImpl to @Path(\"/\") . Step 3 Release the service. Add @RestSchema as the annotation of the service implementation class and specify schemaID, which indicates that the implementation is released as a schema of the current microservice. The code is as follows: java import org.apache.servicecomb.provider.rest.common.RestSchema; // other code omitted @RestSchema(schemaId = \"jaxrsHello\") public class JaxrsHelloImpl implements Hello { // other code omitted } Create the jaxrsHello.bean.xml file in the resources/META-INF/spring directory and configure base-package that performs scanning. The content of the file is as follows: ```xml <context:component-scan base-package=\"org.apache.servicecomb.samples.jaxrs.provider\"/> ``` Step 4 Add service definition file: Add microservice.yaml file into resources folder of your project. Step 5 Add Main class: ```java import org.apache.servicecomb.foundation.common.utils.BeanUtils; import org.apache.servicecomb.foundation.common.utils.Log4jUtils; public class Application { public static void main(String[] args) throws Exception { //initializing log, loading bean(including its parameters), and registering service, more detail can be found here : http://servicecomb.incubator.apache.org/users/application-boot-process/ Log4jUtils.init(); BeanUtils.init(); } } ``` Involved APIs Currently, the JAX-RS development mode supports the following annotation. For details about how to use JAX-RS, see JAX-RS official documentation \u3002 Remarks Location Description javax.ws.rs.Path schema/operation URL path javax.ws.rs.Produces schema/operation Coding/decoding capability supported by the method javax.ws.rs.DELETE operation http method javax.ws.rs.GET operation http method javax.ws.rs.POST operation http method javax.ws.rs.PUT operation http method javax.ws.rs.QueryParam parameter Obtain parameters from query string javax.ws.rs.PathParam parameter Obtain parameters from path, This parameter must be defined in path. javax.ws.rs.HeaderParam parameter Obtain parameters from header. javax.ws.rs.CookieParam parameter Obtain parameters from cookie. NOTE \uff1a - When the method parameter has no annotation and is not an HttpServletRequest parameter, the parameter is of the body type by default. One method supports a maximum of one body-typed parameter. - You are advised to explicitly define the value of the parameter. Otherwise, the parameter name in the API definition is used, such as @QueryParam\\(\"name\"\\) String name String name instead of @QueryParam String name .","title":"Develop with JAX-RS"},{"location":"build-provider/jaxrs/#develop-microservice-with-jax-rs","text":"","title":"Develop Microservice with JAX-RS"},{"location":"build-provider/jaxrs/#concept-description","text":"ServiceComb supports developers in developing services in JAX-RS mode by using JAX-RS.","title":"Concept Description"},{"location":"build-provider/jaxrs/#development-example","text":"Step 1 Import dependencies into your maven project: xml <dependencyManagement> <dependencies> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>java-chassis-dependencies</artifactId> <version>1.0.0-m1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!--transport can optional import through endpoint setting in microservice.yaml, we import both rest and highway as example--> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>transport-rest-vertx</artifactId> </dependency> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>transport-highway</artifactId> </dependency> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>provider-jaxrs</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </dependency> </dependencies> Step 2 Implement the service. JAX-RS is used to describe the development of service code. The implementation of the Hello service is as follows: ```java import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import org.apache.servicecomb.samples.common.schema.models.Person; @Path(\"/jaxrshello\") @Produces(MediaType.APPLICATION_JSON) public class JaxrsHelloImpl { @Path(\"/sayhi\") @POST public String sayHi(String name) { \u3000return \"Hello \" + name; } @Path(\"/sayhello\") @POST public String sayHello(Person person) { return \"Hello person \" + person.getName(); } } ``` Note: PLEASE MAKE SURE TO MARK @Path ON YOUR PRODUCER(JaxrsHelloImpl), OR THE PATH AND METHOD OF PUBLISHED WILL BE INCORRECT! In this sample the Path of sayHi is /jaxrshello/sayhi , and the Path of sayHello is /jaxrshello/sayhello , if you wish them /sayhi and /sayhello , please change the setting of @Path on the JaxrsHelloImpl to @Path(\"/\") . Step 3 Release the service. Add @RestSchema as the annotation of the service implementation class and specify schemaID, which indicates that the implementation is released as a schema of the current microservice. The code is as follows: java import org.apache.servicecomb.provider.rest.common.RestSchema; // other code omitted @RestSchema(schemaId = \"jaxrsHello\") public class JaxrsHelloImpl implements Hello { // other code omitted } Create the jaxrsHello.bean.xml file in the resources/META-INF/spring directory and configure base-package that performs scanning. The content of the file is as follows: ```xml <context:component-scan base-package=\"org.apache.servicecomb.samples.jaxrs.provider\"/> ``` Step 4 Add service definition file: Add microservice.yaml file into resources folder of your project. Step 5 Add Main class: ```java import org.apache.servicecomb.foundation.common.utils.BeanUtils; import org.apache.servicecomb.foundation.common.utils.Log4jUtils; public class Application { public static void main(String[] args) throws Exception { //initializing log, loading bean(including its parameters), and registering service, more detail can be found here : http://servicecomb.incubator.apache.org/users/application-boot-process/ Log4jUtils.init(); BeanUtils.init(); } } ```","title":"Development Example"},{"location":"build-provider/jaxrs/#involved-apis","text":"Currently, the JAX-RS development mode supports the following annotation. For details about how to use JAX-RS, see JAX-RS official documentation \u3002 Remarks Location Description javax.ws.rs.Path schema/operation URL path javax.ws.rs.Produces schema/operation Coding/decoding capability supported by the method javax.ws.rs.DELETE operation http method javax.ws.rs.GET operation http method javax.ws.rs.POST operation http method javax.ws.rs.PUT operation http method javax.ws.rs.QueryParam parameter Obtain parameters from query string javax.ws.rs.PathParam parameter Obtain parameters from path, This parameter must be defined in path. javax.ws.rs.HeaderParam parameter Obtain parameters from header. javax.ws.rs.CookieParam parameter Obtain parameters from cookie. NOTE \uff1a - When the method parameter has no annotation and is not an HttpServletRequest parameter, the parameter is of the body type by default. One method supports a maximum of one body-typed parameter. - You are advised to explicitly define the value of the parameter. Otherwise, the parameter name in the API definition is used, such as @QueryParam\\(\"name\"\\) String name String name instead of @QueryParam String name .","title":"Involved APIs"},{"location":"build-provider/listen-address-and-publish-address/","text":"Service listening address and publishing address Concept Description In JavaChassis, the listening address and publishing address of the service are two independent concepts that can be configured independently: Listening address: refers to the address that the microservice instance listens to when it starts. This configuration item determines which IPs can be accessed by this IP. Publish Address: refers to the address where the microservice instance is registered to the service center. Other microservice instances will obtain information about this instance through the service center and access the service instance based on the publication address, so this configuration item determines which IP other services actually use to access the service. Scene Description The user determines the IP address that the service instance listens to and the IP address requested by other service instances when accessing the instance by configuring the listening address and the publishing address of the service. Configuration instructions The configuration items of the service listening address are servicecomb.rest.address and servicecomb.highway.address , which respectively correspond to the listening address of the rest transmission mode and the highway transmission mode. The configuration rules for both are the same. The following only uses servicecomb.rest.address as an explanation. The configuration item of the service publishing address is servicecomb.service.publishAddress , which can be configured without **. When this item is not configured, JavaChassis will select the publishing address according to the specific rules. Table 1 Service Release Address Effective Rules Rule Number Listening Address Configuration Publishing Address Configuration Effective Delivery Address 1 127.0.0.1 - 127.0.0.1 2 0.0.0.0 - Select the IP address of a network card as the publishing address. Require that the address cannot be a wildcard address, loopback address, or broadcast address 3 Specific IP - Consistent with the listening address 4 * Specific IP Consistent with the published address configuration item 5 * \"{NIC name}\" Specify the IP of the NIC name, note the need to put quotation marks and brackets > Note: > - The address actually listened to by the service instance is always consistent with the listening address configuration item. > - When using the NIC name to configure the publishing address, you need to use double quotation marks to wrap the NIC name placeholder, otherwise the parsing configuration will be reported. > - The NIC name must be the NIC that the host exists. Sample Code An example of the configuration of the microservice.yaml file is as follows: servicecomb: service: publishAddress: \"{eth0}\" # The publishing address, registered to the service center, will be the IP of the eth0 network card rest: address: 0.0.0.0:8080 # Monitor all NIC IPs of the hos highway: address: 0.0.0.0:7070 # Listen to all NIC IPs of the host","title":"Service listening address and publishing address"},{"location":"build-provider/listen-address-and-publish-address/#service-listening-address-and-publishing-address","text":"","title":"Service listening address and publishing address"},{"location":"build-provider/listen-address-and-publish-address/#concept-description","text":"In JavaChassis, the listening address and publishing address of the service are two independent concepts that can be configured independently: Listening address: refers to the address that the microservice instance listens to when it starts. This configuration item determines which IPs can be accessed by this IP. Publish Address: refers to the address where the microservice instance is registered to the service center. Other microservice instances will obtain information about this instance through the service center and access the service instance based on the publication address, so this configuration item determines which IP other services actually use to access the service.","title":"Concept Description"},{"location":"build-provider/listen-address-and-publish-address/#scene-description","text":"The user determines the IP address that the service instance listens to and the IP address requested by other service instances when accessing the instance by configuring the listening address and the publishing address of the service.","title":"Scene Description"},{"location":"build-provider/listen-address-and-publish-address/#configuration-instructions","text":"The configuration items of the service listening address are servicecomb.rest.address and servicecomb.highway.address , which respectively correspond to the listening address of the rest transmission mode and the highway transmission mode. The configuration rules for both are the same. The following only uses servicecomb.rest.address as an explanation. The configuration item of the service publishing address is servicecomb.service.publishAddress , which can be configured without **. When this item is not configured, JavaChassis will select the publishing address according to the specific rules. Table 1 Service Release Address Effective Rules Rule Number Listening Address Configuration Publishing Address Configuration Effective Delivery Address 1 127.0.0.1 - 127.0.0.1 2 0.0.0.0 - Select the IP address of a network card as the publishing address. Require that the address cannot be a wildcard address, loopback address, or broadcast address 3 Specific IP - Consistent with the listening address 4 * Specific IP Consistent with the published address configuration item 5 * \"{NIC name}\" Specify the IP of the NIC name, note the need to put quotation marks and brackets > Note: > - The address actually listened to by the service instance is always consistent with the listening address configuration item. > - When using the NIC name to configure the publishing address, you need to use double quotation marks to wrap the NIC name placeholder, otherwise the parsing configuration will be reported. > - The NIC name must be the NIC that the host exists.","title":"Configuration instructions"},{"location":"build-provider/listen-address-and-publish-address/#sample-code","text":"An example of the configuration of the microservice.yaml file is as follows: servicecomb: service: publishAddress: \"{eth0}\" # The publishing address, registered to the service center, will be the IP of the eth0 network card rest: address: 0.0.0.0:8080 # Monitor all NIC IPs of the hos highway: address: 0.0.0.0:7070 # Listen to all NIC IPs of the host","title":"Sample Code"},{"location":"build-provider/service-configuration/","text":"Load Balancing Policy \u2022 ServiceComb provides a Ribbon-based load balancing solution which can be configured through file. There are different routing policies including random, sequential, policy based on response time weight etc. Service Center Rate Limiting Policy \u2022 Users can set the rate limiting policy in the provider's configuration. By setting the request frequency from a particular micro service, provider can limit the max number of requests per second. Fallback Policy \u2022 A fallback policy is used when a service request is abnormal. Parameter Validation \u2022 Users can set parameter validation rules in the provider's configuration. The rules will validate input parameters when provider APIs are called, so the parameters can be defined in a specific format.","title":"Service configuration"},{"location":"build-provider/service-configuration/#load-balancing-policy","text":"\u2022 ServiceComb provides a Ribbon-based load balancing solution which can be configured through file. There are different routing policies including random, sequential, policy based on response time weight etc. Service Center","title":"Load Balancing Policy"},{"location":"build-provider/service-configuration/#rate-limiting-policy","text":"\u2022 Users can set the rate limiting policy in the provider's configuration. By setting the request frequency from a particular micro service, provider can limit the max number of requests per second.","title":"Rate Limiting Policy"},{"location":"build-provider/service-configuration/#fallback-policy","text":"\u2022 A fallback policy is used when a service request is abnormal.","title":"Fallback Policy"},{"location":"build-provider/service-configuration/#parameter-validation","text":"\u2022 Users can set parameter validation rules in the provider's configuration. The rules will validate input parameters when provider APIs are called, so the parameters can be defined in a specific format.","title":"Parameter Validation"},{"location":"build-provider/springmvc/","text":"Develop Microservice with SpringMVC Concept Description ServiceComb supports Spring MVC annotations to define your REST services. The samples project has a lot of working examples. Development Example Step1 Define the service interface \uff08optional\uff09 Writing a interface for the REST service make it easy to call the service in client in RPC style. public interface Hello { String sayHi(String name); String sayHello(Person person); } Step2 Implement the services The annotations of Spring MVC are used to describe the development of service code. The implementation of the Hello service is as follow: ```java @RestSchema(schemaId = \"springmvcHello\") @RequestMapping(path = \"/springmvchello\", produces = MediaType.APPLICATION_JSON) public class SpringmvcHelloImpl implements Hello { @Override @RequestMapping(path = \"/sayhi\", method = RequestMethod.POST) public String sayHi(@RequestParam(name = \"name\") String name) { return \"Hello \" + name; } @Override @RequestMapping(path = \"/sayhello\", method = RequestMethod.POST) public String sayHello(@RequestBody Person person) { return \"Hello person \" + person.getName(); } } ### Step3 add a component scan \uff08optional\uff09 create `resources/META-INF/spring` folder and add `springmvcprovider.bean.xml`, add component-scan to specify the bean package. This step is optional. The package where main class located is automatically added. ```xml <?xml version=\"1.0\" encoding=\"UTF-8\"?> <beans xmlns=\"http://www.springframework.org/schema/beans\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:context=\"http://www.springframework.org/schema/context\" xsi:schemaLocation=\"http://www.springframework.org/schema/beans classpath:org/springframework/beans/factory/xml/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd\"> <context:component-scan base-package=\"org.apache.servicecomb.samples.springmvc.povider\"/> </beans> Step4 Wrtie a main class This code using log4j as the logger framework. Users can change it to any other favorite logger framework. public class SpringmvcProviderMain { public static void main(String[] args) throws Exception { Log4jUtils.init(); BeanUtils.init(); } } Using POJO as query parameters Description SpringBoot supports to map a bean parameter to HTTP queries. @RequestMapping(\"/hello\") public class HelloService { @RequestMapping(value = \"/sayHello\", method = RequestMethod.GET) public String sayHello(Person person) { System.out.println(\"sayHello is called, person = [\" + person + \"]\"); return \"Hello, your name is \" + person.getName() + \", and age is \" + person.getAge(); } } ServiceComb supports this usage too, but has following constraints. 1. Must not add any mapping annotations, such as @QueryParam 2. Only map to query parameters, headers and forms not supported. 3. Variables name in POJO definition must be the same as query keys. 4. Only primitive and String types supported in POJO, add @JsonIgnore to other types to ignore it. 5. In consumer site(e.g RestTemplate), still need to use query parameters, can not use POJO. Examples Provider service definition @RestSchema(schemaId = \"helloService\") @RequestMapping(\"/hello\") public class HelloService { @RequestMapping(value = \"/sayHello\", method = RequestMethod.GET) public String sayHello(Person person) { System.out.println(\"sayHello is called, person = [\" + person + \"]\"); return \"Hello, your name is \" + person.getName() + \", and age is \" + person.getAge(); } } parameters public class Person { private String name; private int age; @JsonIgnore // add @JsonIgnore to unsupported types private List<Person> children; } Schemas basePath: \"/hello\" paths: /sayHello: get: operationId: \"sayHello\" parameters: # name and age is query parameter - name: \"name\" in: \"query\" required: false type: \"string\" - name: \"age\" in: \"query\" required: false type: \"integer\" format: \"int32\" responses: 200: description: \"response of 200\" schema: type: \"string\" Consumer Call using RPC add an interface java public interface HelloServiceIntf { String sayHello(String name, int age); } call the interface java String result = helloService.sayHello(\"Bob\", 22); // result is \"Hello, your name is Bob, and age is 22\" Call using RestTemplate java String result = restTemplate.getForObject( \"cse://provider-service/hello/sayHello?name=Bob&age=22\", String.class); ServiceComb suppoted Spring MVC annotations and differences ServiceComb supports Spring MVC annotatioins(org.springframework.web.bind.annotation) to define REST interfaces, but they are different. ServiceComb do not support @Controller frameworks and only support @RestController frameworks. Differences in supported annotations Table 1-1 annotations annotation supported notes RequestMapping Yes Can only have one path, multiple path is not supported. GetMapping Yes PutMapping Yes PostMapping Yes DeleteMapping Yes PatchMapping Yes RequestParam Yes CookieValue Yes PathVariable Yes RequestHeader Yes RequestBody Yes supports application/json\uff0cplain/text RequestPart Yes Used in file upload. Using Part\u3001MultipartFile annotations. ResponseBody No @Controller framework is not supported ResponseStatus No Using ApiResponse to define status code RequestAttribute No SessionAttribute No MatrixVariable No ModelAttribute No ControllerAdvice No CrossOrigin No ExceptionHandler No InitBinder No Define a REST service Spring MVC using @RestController to define a REST service\uff0cServiceComb using @RestSchema to define a REST service\uff0cand path value in @RequestMapping is required. @RestSchema(schemaId = \"hello\") @RequestMapping(path = \"/\") @RestController is also supported and equals to @RestSchma(schemaId=\"class name\") . However we suggest using @RestSchema to define a schemaId\uff0cit's more convenient when used in configurations. Cautions : If the classes with @RestController are not expected to be processed by ServiceComb-Java-Chassis and work as REST services, the config item servicecomb.provider.rest.scanRestController=false can be specified to disable the feature mentioned above. Supported data types Spring MVC supports almost all java types in service difinition, e.g. // abstract class public void postData(@RequestBody Object data) // interface public void postData(@RequestBody IPerson interfaceData) // generic without types public void postData(@RequestBody Map rawData) // servlet types public void postData(HttpServletRequest rquest) ServiceComb need to generate Open API schemas based on definition, and support cross language features, so some of there usage is not supported. HttpServletRequest\uff0cObject is supported in latest version, but they are different. We suggest not using there features if possible. please refer to API Constraints for data type supports.","title":"Develop with SpringMVC"},{"location":"build-provider/springmvc/#develop-microservice-with-springmvc","text":"","title":"Develop Microservice with SpringMVC"},{"location":"build-provider/springmvc/#concept-description","text":"ServiceComb supports Spring MVC annotations to define your REST services. The samples project has a lot of working examples.","title":"Concept Description"},{"location":"build-provider/springmvc/#development-example","text":"","title":"Development Example"},{"location":"build-provider/springmvc/#step1-define-the-service-interface-optional","text":"Writing a interface for the REST service make it easy to call the service in client in RPC style. public interface Hello { String sayHi(String name); String sayHello(Person person); }","title":"Step1 Define the service interface \uff08optional\uff09"},{"location":"build-provider/springmvc/#step2-implement-the-services","text":"The annotations of Spring MVC are used to describe the development of service code. The implementation of the Hello service is as follow: ```java @RestSchema(schemaId = \"springmvcHello\") @RequestMapping(path = \"/springmvchello\", produces = MediaType.APPLICATION_JSON) public class SpringmvcHelloImpl implements Hello { @Override @RequestMapping(path = \"/sayhi\", method = RequestMethod.POST) public String sayHi(@RequestParam(name = \"name\") String name) { return \"Hello \" + name; } @Override @RequestMapping(path = \"/sayhello\", method = RequestMethod.POST) public String sayHello(@RequestBody Person person) { return \"Hello person \" + person.getName(); } } ### Step3 add a component scan \uff08optional\uff09 create `resources/META-INF/spring` folder and add `springmvcprovider.bean.xml`, add component-scan to specify the bean package. This step is optional. The package where main class located is automatically added. ```xml <?xml version=\"1.0\" encoding=\"UTF-8\"?> <beans xmlns=\"http://www.springframework.org/schema/beans\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:context=\"http://www.springframework.org/schema/context\" xsi:schemaLocation=\"http://www.springframework.org/schema/beans classpath:org/springframework/beans/factory/xml/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd\"> <context:component-scan base-package=\"org.apache.servicecomb.samples.springmvc.povider\"/> </beans>","title":"Step2 Implement the services"},{"location":"build-provider/springmvc/#step4-wrtie-a-main-class","text":"This code using log4j as the logger framework. Users can change it to any other favorite logger framework. public class SpringmvcProviderMain { public static void main(String[] args) throws Exception { Log4jUtils.init(); BeanUtils.init(); } }","title":"Step4 Wrtie a main class"},{"location":"build-provider/springmvc/#using-pojo-as-query-parameters","text":"","title":"Using POJO as query parameters"},{"location":"build-provider/springmvc/#description","text":"SpringBoot supports to map a bean parameter to HTTP queries. @RequestMapping(\"/hello\") public class HelloService { @RequestMapping(value = \"/sayHello\", method = RequestMethod.GET) public String sayHello(Person person) { System.out.println(\"sayHello is called, person = [\" + person + \"]\"); return \"Hello, your name is \" + person.getName() + \", and age is \" + person.getAge(); } } ServiceComb supports this usage too, but has following constraints. 1. Must not add any mapping annotations, such as @QueryParam 2. Only map to query parameters, headers and forms not supported. 3. Variables name in POJO definition must be the same as query keys. 4. Only primitive and String types supported in POJO, add @JsonIgnore to other types to ignore it. 5. In consumer site(e.g RestTemplate), still need to use query parameters, can not use POJO.","title":"Description"},{"location":"build-provider/springmvc/#examples","text":"","title":"Examples"},{"location":"build-provider/springmvc/#provider","text":"service definition @RestSchema(schemaId = \"helloService\") @RequestMapping(\"/hello\") public class HelloService { @RequestMapping(value = \"/sayHello\", method = RequestMethod.GET) public String sayHello(Person person) { System.out.println(\"sayHello is called, person = [\" + person + \"]\"); return \"Hello, your name is \" + person.getName() + \", and age is \" + person.getAge(); } } parameters public class Person { private String name; private int age; @JsonIgnore // add @JsonIgnore to unsupported types private List<Person> children; } Schemas basePath: \"/hello\" paths: /sayHello: get: operationId: \"sayHello\" parameters: # name and age is query parameter - name: \"name\" in: \"query\" required: false type: \"string\" - name: \"age\" in: \"query\" required: false type: \"integer\" format: \"int32\" responses: 200: description: \"response of 200\" schema: type: \"string\"","title":"Provider"},{"location":"build-provider/springmvc/#consumer","text":"Call using RPC add an interface java public interface HelloServiceIntf { String sayHello(String name, int age); } call the interface java String result = helloService.sayHello(\"Bob\", 22); // result is \"Hello, your name is Bob, and age is 22\" Call using RestTemplate java String result = restTemplate.getForObject( \"cse://provider-service/hello/sayHello?name=Bob&age=22\", String.class);","title":"Consumer"},{"location":"build-provider/springmvc/#servicecomb-suppoted-spring-mvc-annotations-and-differences","text":"ServiceComb supports Spring MVC annotatioins(org.springframework.web.bind.annotation) to define REST interfaces, but they are different. ServiceComb do not support @Controller frameworks and only support @RestController frameworks. Differences in supported annotations","title":"ServiceComb suppoted Spring MVC annotations and differences"},{"location":"build-provider/springmvc/#table-1-1-annotations","text":"annotation supported notes RequestMapping Yes Can only have one path, multiple path is not supported. GetMapping Yes PutMapping Yes PostMapping Yes DeleteMapping Yes PatchMapping Yes RequestParam Yes CookieValue Yes PathVariable Yes RequestHeader Yes RequestBody Yes supports application/json\uff0cplain/text RequestPart Yes Used in file upload. Using Part\u3001MultipartFile annotations. ResponseBody No @Controller framework is not supported ResponseStatus No Using ApiResponse to define status code RequestAttribute No SessionAttribute No MatrixVariable No ModelAttribute No ControllerAdvice No CrossOrigin No ExceptionHandler No InitBinder No Define a REST service Spring MVC using @RestController to define a REST service\uff0cServiceComb using @RestSchema to define a REST service\uff0cand path value in @RequestMapping is required. @RestSchema(schemaId = \"hello\") @RequestMapping(path = \"/\") @RestController is also supported and equals to @RestSchma(schemaId=\"class name\") . However we suggest using @RestSchema to define a schemaId\uff0cit's more convenient when used in configurations. Cautions : If the classes with @RestController are not expected to be processed by ServiceComb-Java-Chassis and work as REST services, the config item servicecomb.provider.rest.scanRestController=false can be specified to disable the feature mentioned above. Supported data types Spring MVC supports almost all java types in service difinition, e.g. // abstract class public void postData(@RequestBody Object data) // interface public void postData(@RequestBody IPerson interfaceData) // generic without types public void postData(@RequestBody Map rawData) // servlet types public void postData(HttpServletRequest rquest) ServiceComb need to generate Open API schemas based on definition, and support cross language features, so some of there usage is not supported. HttpServletRequest\uff0cObject is supported in latest version, but they are different. We suggest not using there features if possible. please refer to API Constraints for data type supports.","title":"Table 1-1 annotations"},{"location":"build-provider/swagger-annotation/","text":"Using Swagger annotations Concept Description Swagger provides a set of annotations for describing interface contracts. Users can use annotations to add descriptions of contracts to their code. ServiceComb supports part of these annotations. Scene Description By using annotations to describe interface contracts, users can use ServiceComb's Swagger contract generation function to automatically generate contract documents that meet the requirements without having to manually write and modify contracts, which can effectively improve development efficiency. Configuration instructions The official description can be found in the [Swagger Annotation Document] (https://github.com/swagger-api/swagger-core/wiki/Annotations-1.5.X). You can refer to the official documentation and this guide to learn how to use annotations to specify the properties of a Swagger contract under the ServiceComb framework. In ServiceComb, Swagger annotations are not required. When a user uses SpringMVC and JAX-RS annotations to annotate microservice methods, ServiceComb can infer the contract information for each microservice method based on the values \u200b\u200bof these annotations. @Api @Api acts at the class level and is used to mark a Class as a Swagger resource in the official Swagger description. However, this annotation is not required in ServiceComb. ServiceComb can determine which classes need to parse the Swagger contract based on @RestSchema and @RpcSchema . Attribute Type Description Tags string set the default tag value of the operation defined under the current Class consumes string specify the MIME types of request in schema level, separated by commas produces string specify the MIME types of response in schema level, separated by commas @SwaggerDefinition Acts at the class level to define information in a Swagger resource. Attribute Type Description info.title string Contract Document Title info.description string Description info.version string contract version number info.termsOfService string Terms of Service info.contact string Contact information, including name, email, url attributes info.license string License information, including name, url attribute info.extensions string Extended Information consumes string Receive Request Format produces string returned response format schemes SwaggerDefinition.Scheme Optional values \u200b\u200bare HTTP/HTTPS/WS/WSS/DEFAULT tags @Tag Tag definition, @Tag contains three attributes: name, description, externalDocs externalDocs @externalDocs External documentation links, including values \u200b\u200band urls @ApiOperation Acts at the method level to describe a Swagger operation. Attribute Type Description value string A brief description of the method, corresponding to the summary field of the Swagger contract operation notes string Details, corresponding to the description field of the Swagger contract operation Tags string label operation label code int HTTP status code for response messages response Class<?> Method return value type responseContainer string The container type that wraps the return value. The optional values \u200b\u200bare List , Set , Map ResponseHeaders @ResponseHeader HTTP response message header, ServiceComb support attribute value of name , response , responseContainer Consumes string specified data format request body Produces string body in response to the data format specified Protocols string the available protocol (schemes), possible values \u200b\u200bare http , https , ws , wss , separated by commas httpMethod string Set HTTP method hidden boolean Weather to hide this method @ApiImplicitParam Acts at the method level, which is used to describe the properties of the parameters of the operation in the Swagger document. Note : ServiceComb can automatically infer parameter names based on code and SpringMVC, JAX-RS annotations. If the parameter name of the @ApiImplicitParam configuration is different from the automatically inferred parameter name, then the parameter of the annotation configuration will be added as a new parameter to the operation in which the annotation is located; otherwise, the property of the parameter with the same name will be overwritten. Attribute Type Description name string parameter name value string Parameter Description required boolean Is this a required parameter dataType string Parameter Data Type paramType string parameter location, valid optional value is path/query/body/header/form allowableValues \u200b\u200b string Range of valid values \u200b\u200bfor allowEmptyValue boolean Whether to allow null values \u200b\u200b allowMultiple boolean Whether to allow multiple values \u200b\u200b(if true, parameters can be used as an array) collectionFormat string In which format the parameter array is specified, the current ServiceComb support value is csv/multi defaultValue string parameter default example string Example value for a non-body parameter format string Allows users to customize the data format. See the Swagger official documentation for details. @ApiImplicitParams @ApiImplicitParams acts on methods, class levels, and is used to batch specify multiple @ApiImplicitParam . Attribute Type Description value @ApiImplicitParam Parameter definition @ApiResponse Used to describe the meaning of the HTTP status code of the returned message. Usually @ApiOperation can represent the HTTP status code of a normal return message. In other cases, the HTTP status code is described by this note. According to the Swagger official documentation, this annotation should not be used directly at the method level, but should be included in @ApiResponses . Attribute Type Description code int Return the HTTP status code of the message message string Description of the return value response Class<?> Type of return value responseContainer string The wrapper for the return value, with an optional value of List/Set/Map responseHeaders @ResponseHeader Describes a set of HTTP headers that return messages. The properties of @ResponseHeader supported by ServiceComb are name , description , response , responseContainer @ApiResponses Acts on methods, class levels, to specify and specify a set of return values. Attribute Type Description value @ApiResponse Return to message description","title":"Use Swagger annotations"},{"location":"build-provider/swagger-annotation/#using-swagger-annotations","text":"","title":"Using Swagger annotations"},{"location":"build-provider/swagger-annotation/#concept-description","text":"Swagger provides a set of annotations for describing interface contracts. Users can use annotations to add descriptions of contracts to their code. ServiceComb supports part of these annotations.","title":"Concept Description"},{"location":"build-provider/swagger-annotation/#scene-description","text":"By using annotations to describe interface contracts, users can use ServiceComb's Swagger contract generation function to automatically generate contract documents that meet the requirements without having to manually write and modify contracts, which can effectively improve development efficiency.","title":"Scene Description"},{"location":"build-provider/swagger-annotation/#configuration-instructions","text":"The official description can be found in the [Swagger Annotation Document] (https://github.com/swagger-api/swagger-core/wiki/Annotations-1.5.X). You can refer to the official documentation and this guide to learn how to use annotations to specify the properties of a Swagger contract under the ServiceComb framework. In ServiceComb, Swagger annotations are not required. When a user uses SpringMVC and JAX-RS annotations to annotate microservice methods, ServiceComb can infer the contract information for each microservice method based on the values \u200b\u200bof these annotations.","title":"Configuration instructions"},{"location":"build-provider/swagger-annotation/#api","text":"@Api acts at the class level and is used to mark a Class as a Swagger resource in the official Swagger description. However, this annotation is not required in ServiceComb. ServiceComb can determine which classes need to parse the Swagger contract based on @RestSchema and @RpcSchema . Attribute Type Description Tags string set the default tag value of the operation defined under the current Class consumes string specify the MIME types of request in schema level, separated by commas produces string specify the MIME types of response in schema level, separated by commas","title":"@Api"},{"location":"build-provider/swagger-annotation/#swaggerdefinition","text":"Acts at the class level to define information in a Swagger resource. Attribute Type Description info.title string Contract Document Title info.description string Description info.version string contract version number info.termsOfService string Terms of Service info.contact string Contact information, including name, email, url attributes info.license string License information, including name, url attribute info.extensions string Extended Information consumes string Receive Request Format produces string returned response format schemes SwaggerDefinition.Scheme Optional values \u200b\u200bare HTTP/HTTPS/WS/WSS/DEFAULT tags @Tag Tag definition, @Tag contains three attributes: name, description, externalDocs externalDocs @externalDocs External documentation links, including values \u200b\u200band urls","title":"@SwaggerDefinition"},{"location":"build-provider/swagger-annotation/#apioperation","text":"Acts at the method level to describe a Swagger operation. Attribute Type Description value string A brief description of the method, corresponding to the summary field of the Swagger contract operation notes string Details, corresponding to the description field of the Swagger contract operation Tags string label operation label code int HTTP status code for response messages response Class<?> Method return value type responseContainer string The container type that wraps the return value. The optional values \u200b\u200bare List , Set , Map ResponseHeaders @ResponseHeader HTTP response message header, ServiceComb support attribute value of name , response , responseContainer Consumes string specified data format request body Produces string body in response to the data format specified Protocols string the available protocol (schemes), possible values \u200b\u200bare http , https , ws , wss , separated by commas httpMethod string Set HTTP method hidden boolean Weather to hide this method","title":"@ApiOperation"},{"location":"build-provider/swagger-annotation/#apiimplicitparam","text":"Acts at the method level, which is used to describe the properties of the parameters of the operation in the Swagger document. Note : ServiceComb can automatically infer parameter names based on code and SpringMVC, JAX-RS annotations. If the parameter name of the @ApiImplicitParam configuration is different from the automatically inferred parameter name, then the parameter of the annotation configuration will be added as a new parameter to the operation in which the annotation is located; otherwise, the property of the parameter with the same name will be overwritten. Attribute Type Description name string parameter name value string Parameter Description required boolean Is this a required parameter dataType string Parameter Data Type paramType string parameter location, valid optional value is path/query/body/header/form allowableValues \u200b\u200b string Range of valid values \u200b\u200bfor allowEmptyValue boolean Whether to allow null values \u200b\u200b allowMultiple boolean Whether to allow multiple values \u200b\u200b(if true, parameters can be used as an array) collectionFormat string In which format the parameter array is specified, the current ServiceComb support value is csv/multi defaultValue string parameter default example string Example value for a non-body parameter format string Allows users to customize the data format. See the Swagger official documentation for details.","title":"@ApiImplicitParam"},{"location":"build-provider/swagger-annotation/#apiimplicitparams","text":"@ApiImplicitParams acts on methods, class levels, and is used to batch specify multiple @ApiImplicitParam . Attribute Type Description value @ApiImplicitParam Parameter definition","title":"@ApiImplicitParams"},{"location":"build-provider/swagger-annotation/#apiresponse","text":"Used to describe the meaning of the HTTP status code of the returned message. Usually @ApiOperation can represent the HTTP status code of a normal return message. In other cases, the HTTP status code is described by this note. According to the Swagger official documentation, this annotation should not be used directly at the method level, but should be included in @ApiResponses . Attribute Type Description code int Return the HTTP status code of the message message string Description of the return value response Class<?> Type of return value responseContainer string The wrapper for the return value, with an optional value of List/Set/Map responseHeaders @ResponseHeader Describes a set of HTTP headers that return messages. The properties of @ResponseHeader supported by ServiceComb are name , description , response , responseContainer","title":"@ApiResponse"},{"location":"build-provider/swagger-annotation/#apiresponses","text":"Acts on methods, class levels, to specify and specify a set of return values. Attribute Type Description value @ApiResponse Return to message description","title":"@ApiResponses"},{"location":"build-provider/thread-pool/","text":"Thread pool Concept Description Thread pool is for executing synchronization business logic. net send/receive or reactive business logic executing in eventloop, is independent of the thread pool By default all synchronization methods are executed in a global built-in thread pool If the business has special requirements, you can specify to use a custom global thread pool, and you can use separate thread pools according to the schemaId or operationId to achieve the effect of the isolated bin. Customize thread pool Implementing a thread pool Choose one of the following methods. Implement the java.util.concurrent.Executor interface In order to support elegant exit, if the internal thread is not set to the daemon thread, you also need to implement the java.io.Closeable interface, responsible for destroying the thread pool. Implement the java.util.concurrent.ExecutorService interface Declare the thread pool of the implementation as a spring bean Enable thread pool Suppose the new thread pool spring bean id is custom-executor Replace the global thread pool servicecomb.executors.default: custom-executor Specify a thread pool dedicated to the schema servicecomb.executors.Provider.${schemaId}: custom-executor Specify a thread pool dedicated to the operation servicecomb.executors.Provider.${schemaId}.${operationId}: custom-executor ServiceComb built-in thread pool In a general thread pool, all threads share a task queue. In this case, all network threads need to apply for the same queue to join the queue. All threads in the thread pool need to grab the task from the same queue. Throughput scenarios, which can lead to competitive conflicts and create performance bottlenecks Therefore, in order to improve performance, ServiceComb's built-in thread pool is actually a wrapper of real thread pools, allowing multiple sets of thread pools to be configured inside, and each network thread is bound to a set of thread pools to reduce contention conflicts. Before version 1.2.0 Configuration default Description servicecomb.executor.default.group 2 Create several sets of thread pools servicecomb.executor.default.thread-per-group CPU count Number of threads per thread pool Version greater than or equal to 1.2.0 Configuration default Description servicecomb.executor.default.group 2 Create several sets of thread pools servicecomb.executor.default.thread-per-group 100 Maximum number of threads per group of thread pools Deprecated\uff0cnew name\uff1amaxThreads-per-group servicecomb.executor.default.coreThreads-per-group 25 Minimum number of threads per group of thread pools Threads are not pre-created, but after they have been created, only threads larger than this value will be destroyed by idle. servicecomb.executor.default.maxThreads-per-group 100 Maximum number of threads per group of thread pools servicecomb.executor.default.maxIdleSecond-per-group 60 Each thread in the thread pool that exceeds coreThreads-per-group will destroy the thread if the idle timeout servicecomb.executor.default.maxQueueSize-per-group Integer.MAX_VALUE Maximum length of the task queue in each group of thread pools","title":"Thread pool"},{"location":"build-provider/thread-pool/#thread-pool","text":"","title":"Thread pool"},{"location":"build-provider/thread-pool/#concept-description","text":"Thread pool is for executing synchronization business logic. net send/receive or reactive business logic executing in eventloop, is independent of the thread pool By default all synchronization methods are executed in a global built-in thread pool If the business has special requirements, you can specify to use a custom global thread pool, and you can use separate thread pools according to the schemaId or operationId to achieve the effect of the isolated bin.","title":"Concept Description"},{"location":"build-provider/thread-pool/#customize-thread-pool","text":"Implementing a thread pool Choose one of the following methods. Implement the java.util.concurrent.Executor interface In order to support elegant exit, if the internal thread is not set to the daemon thread, you also need to implement the java.io.Closeable interface, responsible for destroying the thread pool. Implement the java.util.concurrent.ExecutorService interface Declare the thread pool of the implementation as a spring bean Enable thread pool Suppose the new thread pool spring bean id is custom-executor Replace the global thread pool servicecomb.executors.default: custom-executor Specify a thread pool dedicated to the schema servicecomb.executors.Provider.${schemaId}: custom-executor Specify a thread pool dedicated to the operation servicecomb.executors.Provider.${schemaId}.${operationId}: custom-executor","title":"Customize thread pool"},{"location":"build-provider/thread-pool/#servicecomb-built-in-thread-pool","text":"In a general thread pool, all threads share a task queue. In this case, all network threads need to apply for the same queue to join the queue. All threads in the thread pool need to grab the task from the same queue. Throughput scenarios, which can lead to competitive conflicts and create performance bottlenecks Therefore, in order to improve performance, ServiceComb's built-in thread pool is actually a wrapper of real thread pools, allowing multiple sets of thread pools to be configured inside, and each network thread is bound to a set of thread pools to reduce contention conflicts. Before version 1.2.0 Configuration default Description servicecomb.executor.default.group 2 Create several sets of thread pools servicecomb.executor.default.thread-per-group CPU count Number of threads per thread pool Version greater than or equal to 1.2.0 Configuration default Description servicecomb.executor.default.group 2 Create several sets of thread pools servicecomb.executor.default.thread-per-group 100 Maximum number of threads per group of thread pools Deprecated\uff0cnew name\uff1amaxThreads-per-group servicecomb.executor.default.coreThreads-per-group 25 Minimum number of threads per group of thread pools Threads are not pre-created, but after they have been created, only threads larger than this value will be destroyed by idle. servicecomb.executor.default.maxThreads-per-group 100 Maximum number of threads per group of thread pools servicecomb.executor.default.maxIdleSecond-per-group 60 Each thread in the thread pool that exceeds coreThreads-per-group will destroy the thread if the idle timeout servicecomb.executor.default.maxQueueSize-per-group Integer.MAX_VALUE Maximum length of the task queue in each group of thread pools","title":"ServiceComb built-in thread pool"},{"location":"build-provider/transparent-rpc/","text":"Develop Microservice with Transparent RPC Concept Description The transparent remote procedure call(RPC) development mode is a development mode based on API and API implementation. The service developer does not need to use the description of Spring MVC and JAX-RS. Development Example Step 1 Import dependencies into your maven project: xml <dependencyManagement> <dependencies> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>java-chassis-dependencies</artifactId> <version>1.0.0-m1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!--transport can optional import through endpoint setting in microservice.yaml, we import both rest and highway as example--> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>transport-rest-vertx</artifactId> </dependency> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>transport-highway</artifactId> </dependency> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>provider-pojo</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </dependency> </dependencies> Step 2 Define a service API. Compile the Java API definition based on the API definition defined before development. The code is as follows: java public interface Hello { String sayHi(String name); String sayHello(Person person); } Step 3 implement the service. The implementation of the Hello service is as follows: ```java import org.apache.servicecomb.samples.common.schema.Hello; import org.apache.servicecomb.samples.common.schema.models.Person; public class HelloImpl implements Hello { @Override public String sayHi(String name) { return \"Hello \" + name; } @Override public String sayHello(Person person) { return \"Hello person \" + person.getName(); } } ``` Step 4 Release the service. The transparent RPC development mode supports two service release mode: Spring XML configuration and Annotation configuration: Spring XML configuration Mode: Create the pojoHello.bean.xml file in the resources/META-INF/spring directory and declare the schema in the file. The content of the file is as follows: ```xml <cse:rpc-schema schema-id=\"pojoHello\" implementation=\"org.apache.servicecomb.samples.pojo.provider.PojoHelloImpl\"/> ``` Annotation configuration Mode: @RpcSchema is used to define schema during the API Hello implementation. The code is as follows: ```java import org.apache.servicecomb.provider.pojo.RpcSchema; @RpcSchema(schemaId = \"pojoHello\") public class HelloImpl implements Hello { @Override public String sayHi(String name) { return \"Hello \" + name; } @Override public String sayHello(Person person) { return \"Hello person \" + person.getName(); } } ``` In the pojoHello.bean.xml file of resources/META-INF/spring directory, configure base-package that performs scanning. The content of the file is as follows: ```xml <context:component-scan base-package=\"org.apache.servicecomb.samples.pojo.provider\"/> ``` Note: THE PATH FOR RPC IS ClassName/MethodName , AND THE METHOD IS POST . In this sample the Path of sayHi is /HelloImpl/sayHi , and the Path of sayHello is /HelloImpl/sayHello . NOTE \uff1a Different from the Spring MVC and JAX-RS development modes, the transparent RPC development mode used @RpcSchema instead of @RestSchema . Step 5 Add service definition file: Add microservice.yaml file into resources folder of your project. Step 6 Add Main class: ```java import org.apache.servicecomb.foundation.common.utils.BeanUtils; import org.apache.servicecomb.foundation.common.utils.Log4jUtils; public class Application { public static void main(String[] args) throws Exception { //initializing log, loading bean(including its parameters), and registering service, more detail can be found here : http://servicecomb.incubator.apache.org/users/application-boot-process/ Log4jUtils.init(); BeanUtils.init(); } } ```","title":"Develop with Transparent RPC"},{"location":"build-provider/transparent-rpc/#develop-microservice-with-transparent-rpc","text":"","title":"Develop Microservice with Transparent RPC"},{"location":"build-provider/transparent-rpc/#concept-description","text":"The transparent remote procedure call(RPC) development mode is a development mode based on API and API implementation. The service developer does not need to use the description of Spring MVC and JAX-RS.","title":"Concept Description"},{"location":"build-provider/transparent-rpc/#development-example","text":"Step 1 Import dependencies into your maven project: xml <dependencyManagement> <dependencies> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>java-chassis-dependencies</artifactId> <version>1.0.0-m1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!--transport can optional import through endpoint setting in microservice.yaml, we import both rest and highway as example--> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>transport-rest-vertx</artifactId> </dependency> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>transport-highway</artifactId> </dependency> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>provider-pojo</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </dependency> </dependencies> Step 2 Define a service API. Compile the Java API definition based on the API definition defined before development. The code is as follows: java public interface Hello { String sayHi(String name); String sayHello(Person person); } Step 3 implement the service. The implementation of the Hello service is as follows: ```java import org.apache.servicecomb.samples.common.schema.Hello; import org.apache.servicecomb.samples.common.schema.models.Person; public class HelloImpl implements Hello { @Override public String sayHi(String name) { return \"Hello \" + name; } @Override public String sayHello(Person person) { return \"Hello person \" + person.getName(); } } ``` Step 4 Release the service. The transparent RPC development mode supports two service release mode: Spring XML configuration and Annotation configuration: Spring XML configuration Mode: Create the pojoHello.bean.xml file in the resources/META-INF/spring directory and declare the schema in the file. The content of the file is as follows: ```xml <cse:rpc-schema schema-id=\"pojoHello\" implementation=\"org.apache.servicecomb.samples.pojo.provider.PojoHelloImpl\"/> ``` Annotation configuration Mode: @RpcSchema is used to define schema during the API Hello implementation. The code is as follows: ```java import org.apache.servicecomb.provider.pojo.RpcSchema; @RpcSchema(schemaId = \"pojoHello\") public class HelloImpl implements Hello { @Override public String sayHi(String name) { return \"Hello \" + name; } @Override public String sayHello(Person person) { return \"Hello person \" + person.getName(); } } ``` In the pojoHello.bean.xml file of resources/META-INF/spring directory, configure base-package that performs scanning. The content of the file is as follows: ```xml <context:component-scan base-package=\"org.apache.servicecomb.samples.pojo.provider\"/> ``` Note: THE PATH FOR RPC IS ClassName/MethodName , AND THE METHOD IS POST . In this sample the Path of sayHi is /HelloImpl/sayHi , and the Path of sayHello is /HelloImpl/sayHello . NOTE \uff1a Different from the Spring MVC and JAX-RS development modes, the transparent RPC development mode used @RpcSchema instead of @RestSchema . Step 5 Add service definition file: Add microservice.yaml file into resources folder of your project. Step 6 Add Main class: ```java import org.apache.servicecomb.foundation.common.utils.BeanUtils; import org.apache.servicecomb.foundation.common.utils.Log4jUtils; public class Application { public static void main(String[] args) throws Exception { //initializing log, loading bean(including its parameters), and registering service, more detail can be found here : http://servicecomb.incubator.apache.org/users/application-boot-process/ Log4jUtils.init(); BeanUtils.init(); } } ```","title":"Development Example"},{"location":"build-provider/configuration/downgrade-strategy/","text":"Fallback Concepts A fallback policy is applied when a service request is abnormal. There are three key concepts in fallback: isolation, circuit breaking, and fault tolerance: Isolation is an exception detection mechanism. There are two common \"exception\"s: timeout and overload, which can be controlled by timeout duration and max concurrent requests. Circuit breaking is an exception response mechanism which depends on isolation. Circuit breaking is triggered by the error rate, like the number of bad requests, or the rate of invalid calls. Fault tolerance is an exception handling mechanism that depends on circuit breaking. Fault tolerance is called after a circuit breaking is triggered. Users can set the number of fault tolerance calls in the configuration. Let's combine the 3 concepts: the isolation mechanism detects there are M(the threshold) errors in N requests, the circuit breaking is triggered and make sure there are no more requests sent, and then fault tolerance method is called. Technically the concept definition is the same with Netflix Hystrix, making it easy to understand the config items(Reference: Hystrix Configuration ). ServiceComb provides 2 fault tolerance methods: returning null values and throwing exceptions. Scenario Users configure a fallback policy to handle microservices' exceptions. Configuration Configuration items can be set to be applied to all APIs or a particular method of a microservice. Configuration Scope Configuration by type: items can be applied to Providers and Consumers Configuration by scope: items can be applied to a specific microservice, or [x-schema-id+operationId] All the items in this chapter can be configured in the following format: servicecomb.[namespace].[type].[MicroServiceName].[interface name].[property name] The type can be Consumer or Provider. Specify the [MicroServiceName] to apply configuration to specific microservice. To make the configuration applied to API, we have to specify the API name in the format x-[schema-id+operationId] The possible Isolation config items are as follows: servicecomb.isolation.Consumer.timeout.enabled servicecomb.isolation.Consumer.DemoService.timeout.enabled servicecomb.isolation.Consumer.DemoService.hello.sayHello.timeout.enabled servicecomb.isolation.Provider.timeout.enabled servicecomb.isolation.Provider.DemoService.timeout.enabled servicecomb.isolation.Provider.DemoService.hello.sayHello.timeout.enabled Configuration Items For Providers, the configuration item should be: servicecomb.isolation.Consumer.timeout.enabled For Consumers, the conriguration item should be servicecomb.isolation.Provider.timeout.enabled Table 1-1 The fallback policy config items Configuration Item Default value Value Range Required Description Tips servicecomb.isolation.[type].timeout.enabled FALSE - No Enable timeout detection or not. servicecomb.isolation.[type].timeoutInMilliseconds 30000 - No The timeout duration threshold. servicecomb.isolation.[type].maxConcurrentRequests 10 - No The maximum number of concurrent requests. servicecomb.circuitBreaker.[type].enabled TRUE - No Enable circuit breaking or not. servicecomb.circuitBreaker.[type].forceOpen FALSE - No Force circuit breaker to be enabled regardless of the number of errors. servicecomb.circuitBreaker.[type].forceClosed FALSE - No Force circuit breaker to be disabled. When forceOpen and forceClose are set at the same time, forceOpen will take effect. servicecomb.circuitBreaker.[type].sleepWindowInMilliseconds 15000 - No How long to recover from a circuit breaking. After the recovery, the number of failures will be reset. Note: If the call fails immediately after a recover, the circuit breaker is triggered immediately again. servicecomb.circuitBreaker.[type].requestVolumeThreshold 20 - No The threshold of failed requests within 10 seconds. If the threshold is reached, circuit breaker is triggered. The 10 seconds duration is splitted evenly into 10 segments for error calculation. The calculation will start after 1 second. So circuit breakers are triggered after at least 1 second. servicecomb.circuitBreaker.[type].errorThresholdPercentage 50 - No The threshold of error rate. If the threshold is reached, circuit breaker is triggered. servicecomb.fallback.[type].maxConcurrentRequests 10 - No The max number of concurrent fallback(specified by servicecomb.fallbackpolicy.policy) calls. When the threshold is reached, the fallback method is not called by return exception directly. servicecomb.fallbackpolicy.[type].policy throwException returnNull | throwException No The fallback policy when errors occurred. Caution: Be cautious to set servicecomb.isolation.timeout.enabled to true. All handlers in the handler chain are asynchronously executed, the intermediate handlers' return will make the follow-up handlers processing abandoned. Therefore, we recommend to set servicecomb.isolation.timeout.enabled to be false(by default) and set the network timeout duration servicecomb.request.timeout to 30000. Sample Code servicecomb: handler: chain: Consumer: default: bizkeeper-consumer isolation: Consumer: timeout: enabled: true timeoutInMilliseconds: 30000 circuitBreaker: Consumer: sleepWindowInMilliseconds: 15000 requestVolumeThreshold: 20 fallback: Consumer: enabled: true fallbackpolicy: Consumer: policy: throwException NOTE: You need to enable service governance for fallback. The corresponding provider handler bizkeeper-provider , and the consumer handler is bizkeeper-consumer .","title":"Fallback Policy"},{"location":"build-provider/configuration/downgrade-strategy/#fallback","text":"","title":"Fallback"},{"location":"build-provider/configuration/downgrade-strategy/#concepts","text":"A fallback policy is applied when a service request is abnormal. There are three key concepts in fallback: isolation, circuit breaking, and fault tolerance: Isolation is an exception detection mechanism. There are two common \"exception\"s: timeout and overload, which can be controlled by timeout duration and max concurrent requests. Circuit breaking is an exception response mechanism which depends on isolation. Circuit breaking is triggered by the error rate, like the number of bad requests, or the rate of invalid calls. Fault tolerance is an exception handling mechanism that depends on circuit breaking. Fault tolerance is called after a circuit breaking is triggered. Users can set the number of fault tolerance calls in the configuration. Let's combine the 3 concepts: the isolation mechanism detects there are M(the threshold) errors in N requests, the circuit breaking is triggered and make sure there are no more requests sent, and then fault tolerance method is called. Technically the concept definition is the same with Netflix Hystrix, making it easy to understand the config items(Reference: Hystrix Configuration ). ServiceComb provides 2 fault tolerance methods: returning null values and throwing exceptions.","title":"Concepts"},{"location":"build-provider/configuration/downgrade-strategy/#scenario","text":"Users configure a fallback policy to handle microservices' exceptions.","title":"Scenario"},{"location":"build-provider/configuration/downgrade-strategy/#configuration","text":"Configuration items can be set to be applied to all APIs or a particular method of a microservice.","title":"Configuration"},{"location":"build-provider/configuration/downgrade-strategy/#configuration-scope","text":"Configuration by type: items can be applied to Providers and Consumers Configuration by scope: items can be applied to a specific microservice, or [x-schema-id+operationId] All the items in this chapter can be configured in the following format: servicecomb.[namespace].[type].[MicroServiceName].[interface name].[property name] The type can be Consumer or Provider. Specify the [MicroServiceName] to apply configuration to specific microservice. To make the configuration applied to API, we have to specify the API name in the format x-[schema-id+operationId] The possible Isolation config items are as follows: servicecomb.isolation.Consumer.timeout.enabled servicecomb.isolation.Consumer.DemoService.timeout.enabled servicecomb.isolation.Consumer.DemoService.hello.sayHello.timeout.enabled servicecomb.isolation.Provider.timeout.enabled servicecomb.isolation.Provider.DemoService.timeout.enabled servicecomb.isolation.Provider.DemoService.hello.sayHello.timeout.enabled","title":"Configuration Scope"},{"location":"build-provider/configuration/downgrade-strategy/#configuration-items","text":"For Providers, the configuration item should be: servicecomb.isolation.Consumer.timeout.enabled For Consumers, the conriguration item should be servicecomb.isolation.Provider.timeout.enabled Table 1-1 The fallback policy config items Configuration Item Default value Value Range Required Description Tips servicecomb.isolation.[type].timeout.enabled FALSE - No Enable timeout detection or not. servicecomb.isolation.[type].timeoutInMilliseconds 30000 - No The timeout duration threshold. servicecomb.isolation.[type].maxConcurrentRequests 10 - No The maximum number of concurrent requests. servicecomb.circuitBreaker.[type].enabled TRUE - No Enable circuit breaking or not. servicecomb.circuitBreaker.[type].forceOpen FALSE - No Force circuit breaker to be enabled regardless of the number of errors. servicecomb.circuitBreaker.[type].forceClosed FALSE - No Force circuit breaker to be disabled. When forceOpen and forceClose are set at the same time, forceOpen will take effect. servicecomb.circuitBreaker.[type].sleepWindowInMilliseconds 15000 - No How long to recover from a circuit breaking. After the recovery, the number of failures will be reset. Note: If the call fails immediately after a recover, the circuit breaker is triggered immediately again. servicecomb.circuitBreaker.[type].requestVolumeThreshold 20 - No The threshold of failed requests within 10 seconds. If the threshold is reached, circuit breaker is triggered. The 10 seconds duration is splitted evenly into 10 segments for error calculation. The calculation will start after 1 second. So circuit breakers are triggered after at least 1 second. servicecomb.circuitBreaker.[type].errorThresholdPercentage 50 - No The threshold of error rate. If the threshold is reached, circuit breaker is triggered. servicecomb.fallback.[type].maxConcurrentRequests 10 - No The max number of concurrent fallback(specified by servicecomb.fallbackpolicy.policy) calls. When the threshold is reached, the fallback method is not called by return exception directly. servicecomb.fallbackpolicy.[type].policy throwException returnNull | throwException No The fallback policy when errors occurred. Caution: Be cautious to set servicecomb.isolation.timeout.enabled to true. All handlers in the handler chain are asynchronously executed, the intermediate handlers' return will make the follow-up handlers processing abandoned. Therefore, we recommend to set servicecomb.isolation.timeout.enabled to be false(by default) and set the network timeout duration servicecomb.request.timeout to 30000.","title":"Configuration Items"},{"location":"build-provider/configuration/downgrade-strategy/#sample-code","text":"servicecomb: handler: chain: Consumer: default: bizkeeper-consumer isolation: Consumer: timeout: enabled: true timeoutInMilliseconds: 30000 circuitBreaker: Consumer: sleepWindowInMilliseconds: 15000 requestVolumeThreshold: 20 fallback: Consumer: enabled: true fallbackpolicy: Consumer: policy: throwException NOTE: You need to enable service governance for fallback. The corresponding provider handler bizkeeper-provider , and the consumer handler is bizkeeper-consumer .","title":"Sample Code"},{"location":"build-provider/configuration/parameter-validator/","text":"Parameter Validation Scenario Users can set parameter validation rules in the provider's configuration. The rules will validate input parameters when provider APIs are called, so the parameters can be defined in a specific format. Configuration instructions Add the pom dependency of swagger-invocation-validator: xml <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>swagger-invocation-validator</artifactId> </dependency> Add validator annotations to the code that requires validation by the JSR 349 specification, such as @NotNull, @Min, @Max, etc. Sample Code Interface parameter verification @RestSchema(schemaId = \"validator\") @Path(\"/validator\") @Produces(MediaType.APPLICATION_JSON) public class Validator { @Path(\"/add\") @POST public int add(@FormParam(\"a\") int a, @Min(20) @FormParam(\"b\") int b) { return a + b; } @Path(\"/sayhi/{name}\") @PUT public String sayHi(@Length(min = 3) @PathParam(\"name\") String name) { ContextUtils.getInvocationContext().setStatus(202); return name + \" sayhi\"; } @Path(\"/sayhello\") @POST public Student sayHello(@Valid Student student) { student.setName(\"hello \" + student.getName()); student.setAge(student.getAge()); return student; } } bean class validation Add @Valid in front of the incoming Student object, like the method sayHello(@Valid Student student) shown above. public class Student { @NotNull private String name; @Max(20) private int age; public void setName(String name) { this.name = name; } public String getName() { return this.name; } public void setAge(int age) { this.age = age; } public int getAge() { return age; } } Custom return exception The default parameter validator ParameterValidator has implemented the interface ProducerInvokeExtension to handle the required parameter validation with the JSR 349 specification. If any parameter validation fails, the default error is BAD_REQUEST(400, \"Bad Request\"). Return error can be customized with the SPI mechanism. Developer can customize the returned error information by implementing the interface ExceptionToProducerResponseConverter, taking the ConstraintViolationExceptionToProducerResponseConverter as an example. 1. Implement the ExceptionToProducerResponseConverter interface, override the method, the return value of the getOrder method indicates the priority of the validator. The smaller the value, the higher the priority. ```java public class ConstraintViolationExceptionToProducerResponseConverter implements ExceptionToProducerResponseConverter<ConstraintViolationException> { @Override public Class<ConstraintViolationException> getExceptionClass() { return ConstraintViolationException.class; } @Override public Response convert(SwaggerInvocation swaggerInvocation, ConstraintViolationException e) { return Response.createFail(new InvocationException(Status.BAD_REQUEST, e.getConstraintViolations().toString())); } @Override public int getOrder() { return -100; } } ``` Add a file in the services folder under META-INF, with the implemented interface x.x.x.ExceptionToProducerResponseConverter(with package name) as the name, and the implementation class x.x.x.ConstraintViolationExceptionToProducerResponseConverter(with package name) as the content.","title":"Parameter Validator"},{"location":"build-provider/configuration/parameter-validator/#parameter-validation","text":"","title":"Parameter Validation"},{"location":"build-provider/configuration/parameter-validator/#scenario","text":"Users can set parameter validation rules in the provider's configuration. The rules will validate input parameters when provider APIs are called, so the parameters can be defined in a specific format.","title":"Scenario"},{"location":"build-provider/configuration/parameter-validator/#configuration-instructions","text":"Add the pom dependency of swagger-invocation-validator: xml <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>swagger-invocation-validator</artifactId> </dependency> Add validator annotations to the code that requires validation by the JSR 349 specification, such as @NotNull, @Min, @Max, etc.","title":"Configuration instructions"},{"location":"build-provider/configuration/parameter-validator/#sample-code","text":"Interface parameter verification @RestSchema(schemaId = \"validator\") @Path(\"/validator\") @Produces(MediaType.APPLICATION_JSON) public class Validator { @Path(\"/add\") @POST public int add(@FormParam(\"a\") int a, @Min(20) @FormParam(\"b\") int b) { return a + b; } @Path(\"/sayhi/{name}\") @PUT public String sayHi(@Length(min = 3) @PathParam(\"name\") String name) { ContextUtils.getInvocationContext().setStatus(202); return name + \" sayhi\"; } @Path(\"/sayhello\") @POST public Student sayHello(@Valid Student student) { student.setName(\"hello \" + student.getName()); student.setAge(student.getAge()); return student; } } bean class validation Add @Valid in front of the incoming Student object, like the method sayHello(@Valid Student student) shown above. public class Student { @NotNull private String name; @Max(20) private int age; public void setName(String name) { this.name = name; } public String getName() { return this.name; } public void setAge(int age) { this.age = age; } public int getAge() { return age; } }","title":"Sample Code"},{"location":"build-provider/configuration/parameter-validator/#custom-return-exception","text":"The default parameter validator ParameterValidator has implemented the interface ProducerInvokeExtension to handle the required parameter validation with the JSR 349 specification. If any parameter validation fails, the default error is BAD_REQUEST(400, \"Bad Request\"). Return error can be customized with the SPI mechanism. Developer can customize the returned error information by implementing the interface ExceptionToProducerResponseConverter, taking the ConstraintViolationExceptionToProducerResponseConverter as an example. 1. Implement the ExceptionToProducerResponseConverter interface, override the method, the return value of the getOrder method indicates the priority of the validator. The smaller the value, the higher the priority. ```java public class ConstraintViolationExceptionToProducerResponseConverter implements ExceptionToProducerResponseConverter<ConstraintViolationException> { @Override public Class<ConstraintViolationException> getExceptionClass() { return ConstraintViolationException.class; } @Override public Response convert(SwaggerInvocation swaggerInvocation, ConstraintViolationException e) { return Response.createFail(new InvocationException(Status.BAD_REQUEST, e.getConstraintViolations().toString())); } @Override public int getOrder() { return -100; } } ``` Add a file in the services folder under META-INF, with the implemented interface x.x.x.ExceptionToProducerResponseConverter(with package name) as the name, and the implementation class x.x.x.ConstraintViolationExceptionToProducerResponseConverter(with package name) as the content.","title":"Custom return exception"},{"location":"build-provider/configuration/ratelimite-strategy/","text":"Rate Limiting Policy Scenario Users can set the rate limiting policy in the provider's configuration. By setting the request frequency from a particular micro service, provider can limit the max number of requests per second. Cautions There may be a small difference between the rate limit and actual traffic. The provider's rate limit control is for service rather than security. To prevent distributed denial of service(DDos) attacks, you need to take other measures. Traffic control is scoped to microservice rather than instance. Consume a consumer microservice has 3 instances, and calls a provider service. After configuring the rate limit policy, the provider won't distinguish which consumer instance makes the request, but take all requests together as the 'consume request' for rate limiting. Configuration Rate limiting policies are configured in the microservice.yaml file. The table below shows all the configuration items. To enable the provider's rate limit policy, you also need to configure the rate limiting handler in the server's handler chain and add dependencies in the pom.xml file. An example of rate limit configuration in microservice.yaml: servicecomb: handler: chain: Provider: default: qps-flowcontrol-provider Add the handler-flowcontrol-qps dependency in the pom.xml file: <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>handler-flowcontrol-qps</artifactId> <version>1.0.0-m1</version> </dependency> QPS rate limit configuration items Configuration Item Default Value Value Range Required Description Remarks servicecomb.flowcontrol.Provider.qps.enabled true true/false No Enable provider's traffic control or not - servicecomb.flowcontrol.Provider.qps.limit.[ServiceName] 2147483647\uff08max int\uff09 (0,2147483647]\uff0cInteger No Specifies the number of requests allowed per second. This parameter can be configured to microservice/schema/operation, the latter has a higher priorty servicecomb.flowcontrol.Provider.qps.global.limit 2147483647\uff08max int\uff09 (0,2147483647]\uff0cInteger No Specifies the provider's total number of requests If no configuration is set for any specific microservice, this parameter takes effect Notes: The ServiceName in provider's rate limit config is the name of the consumer that calls the provider. While schema and operation is the provider's own config item. That is, the rate limit policy controls the consumer requests that call the provider's schema or operation.","title":"Rate Limiting Policy"},{"location":"build-provider/configuration/ratelimite-strategy/#rate-limiting-policy","text":"","title":"Rate Limiting Policy"},{"location":"build-provider/configuration/ratelimite-strategy/#scenario","text":"Users can set the rate limiting policy in the provider's configuration. By setting the request frequency from a particular micro service, provider can limit the max number of requests per second.","title":"Scenario"},{"location":"build-provider/configuration/ratelimite-strategy/#cautions","text":"There may be a small difference between the rate limit and actual traffic. The provider's rate limit control is for service rather than security. To prevent distributed denial of service(DDos) attacks, you need to take other measures. Traffic control is scoped to microservice rather than instance. Consume a consumer microservice has 3 instances, and calls a provider service. After configuring the rate limit policy, the provider won't distinguish which consumer instance makes the request, but take all requests together as the 'consume request' for rate limiting.","title":"Cautions"},{"location":"build-provider/configuration/ratelimite-strategy/#configuration","text":"Rate limiting policies are configured in the microservice.yaml file. The table below shows all the configuration items. To enable the provider's rate limit policy, you also need to configure the rate limiting handler in the server's handler chain and add dependencies in the pom.xml file. An example of rate limit configuration in microservice.yaml: servicecomb: handler: chain: Provider: default: qps-flowcontrol-provider Add the handler-flowcontrol-qps dependency in the pom.xml file: <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>handler-flowcontrol-qps</artifactId> <version>1.0.0-m1</version> </dependency> QPS rate limit configuration items Configuration Item Default Value Value Range Required Description Remarks servicecomb.flowcontrol.Provider.qps.enabled true true/false No Enable provider's traffic control or not - servicecomb.flowcontrol.Provider.qps.limit.[ServiceName] 2147483647\uff08max int\uff09 (0,2147483647]\uff0cInteger No Specifies the number of requests allowed per second. This parameter can be configured to microservice/schema/operation, the latter has a higher priorty servicecomb.flowcontrol.Provider.qps.global.limit 2147483647\uff08max int\uff09 (0,2147483647]\uff0cInteger No Specifies the provider's total number of requests If no configuration is set for any specific microservice, this parameter takes effect Notes: The ServiceName in provider's rate limit config is the name of the consumer that calls the provider. While schema and operation is the provider's own config item. That is, the rate limit policy controls the consumer requests that call the provider's schema or operation.","title":"Configuration"},{"location":"build-provider/definition/heartbeats/","text":"\u573a\u666f\u63cf\u8ff0 \u5f53\u5fae\u670d\u52a1\u5b9e\u4f8b\u6ce8\u518c\u5230\u670d\u52a1\u4e2d\u5fc3\u540e\uff0c\u5fae\u670d\u52a1\u9700\u8981\u5b9a\u65f6\u5411\u670d\u52a1\u4e2d\u5fc3\u53d1\u9001\u5fc3\u8df3\u3002\u82e5\u670d\u52a1\u4e2d\u5fc3\u5728\u4e00\u5b9a\u65f6\u95f4\u5185\u6ca1\u6709\u6536\u5230\u5fc3\u8df3\u4fe1\u606f\uff0c\u5219\u4f1a\u6ce8\u9500\u6b64\u5b9e\u4f8b\u3002 \u6d89\u53caAPI org.apache.servicecomb.serviceregistry.client.ServiceRegistryClient \uff1a\u670d\u52a1\u4e2d\u5fc3\u5ba2\u6237\u7aef \u914d\u7f6e\u8bf4\u660e ServiceRegistryClient \u63d0\u4f9b\u4e86\u53d1\u9001\u5fc3\u8df3\u7684\u65b9\u6cd5 heartbeat \uff0c\u7528\u6237\u76f4\u63a5\u8c03\u7528\u5373\u53ef\uff0c\u793a\u4f8b\u4ee3\u7801\u5982\u4e0b\uff1a public static void main(String[] args) throws Exception { // \u9996\u5148\u9700\u8981\u6ce8\u518c\u5fae\u670d\u52a1\u548c\u5b9e\u4f8b\u2026\u2026 // \u53d1\u9001\u5fc3\u8df3\uff0c\u4e0d\u7136\u5b9e\u4f8b\u4f1a\u6d88\u5931 while (true) { System.out.println(\"heartbeat sended:\" + client.heartbeat(service2.getServiceId(), instance.getInstanceId())); Thread.sleep(3000); } }","title":"Heartbeats"},{"location":"build-provider/definition/heartbeats/#_1","text":"\u5f53\u5fae\u670d\u52a1\u5b9e\u4f8b\u6ce8\u518c\u5230\u670d\u52a1\u4e2d\u5fc3\u540e\uff0c\u5fae\u670d\u52a1\u9700\u8981\u5b9a\u65f6\u5411\u670d\u52a1\u4e2d\u5fc3\u53d1\u9001\u5fc3\u8df3\u3002\u82e5\u670d\u52a1\u4e2d\u5fc3\u5728\u4e00\u5b9a\u65f6\u95f4\u5185\u6ca1\u6709\u6536\u5230\u5fc3\u8df3\u4fe1\u606f\uff0c\u5219\u4f1a\u6ce8\u9500\u6b64\u5b9e\u4f8b\u3002","title":"\u573a\u666f\u63cf\u8ff0"},{"location":"build-provider/definition/heartbeats/#api","text":"org.apache.servicecomb.serviceregistry.client.ServiceRegistryClient \uff1a\u670d\u52a1\u4e2d\u5fc3\u5ba2\u6237\u7aef","title":"\u6d89\u53caAPI"},{"location":"build-provider/definition/heartbeats/#_2","text":"ServiceRegistryClient \u63d0\u4f9b\u4e86\u53d1\u9001\u5fc3\u8df3\u7684\u65b9\u6cd5 heartbeat \uff0c\u7528\u6237\u76f4\u63a5\u8c03\u7528\u5373\u53ef\uff0c\u793a\u4f8b\u4ee3\u7801\u5982\u4e0b\uff1a public static void main(String[] args) throws Exception { // \u9996\u5148\u9700\u8981\u6ce8\u518c\u5fae\u670d\u52a1\u548c\u5b9e\u4f8b\u2026\u2026 // \u53d1\u9001\u5fc3\u8df3\uff0c\u4e0d\u7136\u5b9e\u4f8b\u4f1a\u6d88\u5931 while (true) { System.out.println(\"heartbeat sended:\" + client.heartbeat(service2.getServiceId(), instance.getInstanceId())); Thread.sleep(3000); } }","title":"\u914d\u7f6e\u8bf4\u660e"},{"location":"build-provider/definition/isolate-relationship/","text":"\u573a\u666f\u63cf\u8ff0 \u8fdb\u884c\u670d\u52a1\u53d1\u73b0\u7684\u65f6\u5019\uff0c\u5f00\u53d1\u8005\u9700\u8981\u4e86\u89e3\u672c\u5fae\u670d\u52a1\u80fd\u591f\u53d1\u73b0\u90a3\u4e9b\u5176\u4ed6\u670d\u52a1\u7684\u5b9e\u4f8b\u3002ServiceComb\u63d0\u4f9b\u4e86\u5206\u5c42\u6b21\u7684\u5b9e\u4f8b\u9694\u79bb\u3002 \u5fae\u670d\u52a1\u5b9e\u4f8b\u5206\u5c42\u7ba1\u7406 \u8981\u4e86\u89e3\u5b9e\u4f8b\u95f4\u7684\u9694\u79bb\u5c42\u6b21\uff0c\u9996\u5148\u9700\u8981\u4e86\u89e3ServiceComb\u5b9a\u4e49\u7684\u4e00\u4e2a\u4f53\u7cfb\u5b8c\u5907\u7684\u5fae\u670d\u52a1\u7cfb\u7edf\u7ed3\u6784\uff1a \u5728\u5fae\u670d\u52a1\u7cfb\u7edf\u7ed3\u6784\u4e2d\uff0c\u9876\u5c42\u662f\u201c\u9879\u76ee\u201d\uff0c\u5728\u9879\u76ee\u4e0b\u5206\u4e3a\u591a\u4e2a\u79df\u6237\uff0c\u79df\u6237\u4e2d\u5305\u542b\u591a\u4e2a\u5e94\u7528\uff0c\u800c\u6bcf\u4e2a\u5e94\u7528\u7531\u5305\u542b\u591a\u4e2a\u73af\u5883\uff0c\u5373\u6d4b\u8bd5\u548c\u751f\u4ea7\u73af\u5883\u53ef\u4ee5\u5206\u5f00\u3002\u5728\u67d0\u4e2a\u7279\u5b9a\u5e94\u7528\u7684\u7279\u5b9a\u73af\u5883\u4e2d\uff0c\u5305\u542b\u591a\u4e2a\u5fae\u670d\u52a1\uff0c\u800c\u4e00\u4e2a\u5fae\u670d\u52a1\u53c8\u53ef\u4ee5\u540c\u65f6\u5b58\u5728\u591a\u4e2a\u7248\u672c\u3002\u4ee5\u4e0a\uff0c\u662f\u6240\u6709\u9759\u6001\u5143\u6570\u636e\u7684\u8303\u7574\uff0c\u67d0\u4e2a\u7279\u5b9a\u670d\u52a1\u7684\u7279\u5b9a\u7248\u672c\u5219\u5305\u542b\u591a\u4e2a\u5728\u8fd0\u884c\u65f6\u6ce8\u518c\u4e0a\u6765\u7684\u5fae\u670d\u52a1\u5b9e\u4f8b\uff0c\u56e0\u4e3a\u670d\u52a1\u5b9e\u4f8b\u7684\u4fe1\u606f\u5728\u8fd0\u884c\u65f6\u968f\u7740\u7cfb\u7edf\u7684\u4f38\u7f29\u3001\u6545\u969c\u7b49\u539f\u56e0\u662f\u52a8\u6001\u53d8\u5316\u7684\uff0c\u6240\u4ee5\u670d\u52a1\u5b9e\u4f8b\u7684\u8def\u7531\u4fe1\u606f\u53c8\u4e3a\u52a8\u6001\u6570\u636e\u3002\u901a\u8fc7\u5206\u5c42\u7ba1\u7406\u5fae\u670d\u52a1\u7684\u8fd9\u4e9b\u6570\u636e\uff0c\u4e5f\u5c31\u81ea\u7136\u800c\u7136\u7684\u5b9e\u73b0\u4e86\u5b9e\u4f8b\u4e4b\u95f4\u7684\u903b\u8f91\u9694\u79bb\u3002 \u9694\u79bb\u5c42\u6b21\u8bf4\u660e ServiceComb\u652f\u6301\u81ea\u5b9a\u4e49\u5206\u5c42\u914d\u7f6e\uff0c\u6ee1\u8db3\u7528\u6237\u7684\u5b9e\u4f8b\u5206\u5c42\u7ba1\u7406\u9700\u6c42\uff0c\u4ee5\u4e0b\u662f\u5177\u4f53\u914d\u7f6e\u8bf4\u660e\u3002 \u5e94\u7528ID \u901a\u8fc7APPLICATIOIN_ID\u6765\u5b9a\u4e49\uff0c\u7f3a\u7701\u503c\u4e3adefault\u3002\u5fae\u670d\u52a1\u5728\u53d1\u73b0\u5b9e\u4f8b\u7684\u65f6\u5019\uff0c\u7f3a\u7701\u53ea\u80fd\u591f\u88ab\u76f8\u540cAPPLICATIOIN_ID\u4e0b\u7684\u6d88\u8d39\u8005\u53d1\u73b0\u3002 Domain\u540d\u79f0 \u901a\u8fc7cse.config.client.domainName\u6765\u5b9a\u4e49\uff0c\u7f3a\u7701\u503c\u4e3adefault\u3002\u4f5c\u4e3a\u5fae\u670d\u52a1\u63d0\u4f9b\u8005\uff0c\u7528\u4e8e\u8868\u660e\u81ea\u8eab\u6240\u5c5e\u79df\u6237\u4fe1\u606f\u3002\u5fae\u670d\u52a1\u5728\u53d1\u73b0\u5b9e\u4f8b\u7684\u65f6\u5019\uff0c\u53ea\u80fd\u88ab\u76f8\u540c\u79df\u6237\u4e0b\u7684\u6d88\u8d39\u8005\u53d1\u73b0\u3002 \u6570\u636e\u4e2d\u5fc3\u4fe1\u606f \u6570\u636e\u4e2d\u5fc3\u5305\u62ec3\u4e2a\u5c5e\u6027\uff1acse.datacenter.name\uff0c cse.datacenter.region, cse.datacenter.availableZone\u3002\u6570\u636e\u4e2d\u5fc3\u4fe1\u606f\u4e0d\u63d0\u4f9b\u9694\u79bb\u80fd\u529b\uff0c\u5fae\u670d\u52a1\u53ef\u4ee5\u53d1\u73b0\u5176\u4ed6\u6570\u636e\u4e2d\u5fc3\u7684\u5b9e\u4f8b\u3002\u4f46\u662f\u53ef\u4ee5\u901a\u8fc7\u542f\u7528\u5b9e\u4f8b\u4eb2\u548c\u6027\uff0c\u6765\u4f18\u5148\u5f80\u6307\u5b9a\u7684\u533a\u57df\u6216\u8005Zone\u53d1\u6d88\u606f\uff1a cse: loadbalance: serverListFilters: zoneaware serverListFilter: zoneaware: className: org.apache.servicecomb.loadbalance.filter.ZoneAwareServerListFilterExt \u8fd9\u6837\u914d\u7f6e\u540e\uff0c\u5ba2\u6237\u7aef\u5728\u8def\u7531\u7684\u65f6\u5019\uff0c\u4f1a\u4f18\u5148\u5c06\u8bf7\u6c42\u8f6c\u53d1\u5230zone/region\u90fd\u76f8\u540c\u7684\u5b9e\u4f8b\uff0c\u7136\u540e\u662fregion\u76f8\u540c\uff0c\u4f46zone\u4e0d\u76f8\u540c\u7684\u5b9e\u4f8b\uff0c\u90fd\u4e0d\u76f8\u540c\u7684\u65f6\u5019\uff0c\u5219\u6309\u7167\u8def\u7531\u89c4\u5219\u9009\u62e9\u4e00\u4e2a\u3002\u4eb2\u548c\u6027\u4e0d\u662f\u903b\u8f91\u9694\u79bb\uff0c\u53ea\u8981\u5b9e\u4f8b\u4e4b\u95f4\u7f51\u7edc\u662f\u8054\u901a\u7684\uff0c\u90a3\u4e48\u90fd\u6709\u53ef\u80fd\u8bbf\u95ee\u5230\uff1b\u5982\u679c\u7f51\u7edc\u4e0d\u901a\uff0c\u5219\u4f1a\u8bbf\u95ee\u5931\u8d25\u3002 \u73af\u5883\u4fe1\u606f \u5728yaml\u6587\u4ef6\u91cc\u901a\u8fc7service_description.environment\u6765\u914d\u7f6e\uff0c\u540c\u65f6\u652f\u6301\u901a\u8fc7\u73af\u5883\u53d8\u91cfSERVICECOMB_ENV\u914d\u7f6e\uff0c\u4ec5\u652f\u6301\u4ee5\u4e0b\u679a\u4e3e\u503c development,testing,acceptance,production\uff0c\u7f3a\u7701\u503c\u4e3a\"\"(\u7a7a)\u3002\u5fae\u670d\u52a1\u5728\u53d1\u73b0\u5b9e\u4f8b\u7684\u65f6\u5019\uff0c\u7f3a\u7701\u53ea\u80fd\u591f\u88ab\u76f8\u540cenvironment\u4e0b\u7684\u6d88\u8d39\u8005\u53d1\u73b0\u3002 service_description: environment: production \u4e0e\u534e\u4e3a\u516c\u6709\u4e91\u6982\u5ff5\u7684\u5bf9\u5e94\u5173\u7cfb \u534e\u4e3a\u516c\u6709\u4e91\u6709\u7c7b\u4f3c\u7684\u6982\u5ff5\uff0c\u5e94\u7528\u3001\u79df\u6237\u3001Project\u3001Cluster\u7b49\uff0c\u5728\u5b9e\u9645\u5e94\u7528\u7684\u65f6\u5019\uff0c\u53ef\u4ee5\u5206\u522b\u5bf9\u5e94\u5230ServiceComb\u7684\u5e94\u7528\u3001\u79df\u6237\u3001Domain\u3001Zone\u7b49\u4fe1\u606f\u3002\u6bd4\u5982\u5728\u516c\u6709\u4e91\u4e0a\u5982\u679cCluster\u5171\u4eabProject\uff0c\u90a3\u4e48\u5c31\u53ef\u4ee5\u901a\u8fc7zone\u6765\u5bf9\u5e94Cluster\uff0c\u5b9e\u73b0\u96c6\u7fa4\u4e4b\u95f4\u7684\u4eb2\u548c\u6027\u8bbf\u95ee\u3002","title":"Isolate relationship"},{"location":"build-provider/definition/isolate-relationship/#_1","text":"\u8fdb\u884c\u670d\u52a1\u53d1\u73b0\u7684\u65f6\u5019\uff0c\u5f00\u53d1\u8005\u9700\u8981\u4e86\u89e3\u672c\u5fae\u670d\u52a1\u80fd\u591f\u53d1\u73b0\u90a3\u4e9b\u5176\u4ed6\u670d\u52a1\u7684\u5b9e\u4f8b\u3002ServiceComb\u63d0\u4f9b\u4e86\u5206\u5c42\u6b21\u7684\u5b9e\u4f8b\u9694\u79bb\u3002","title":"\u573a\u666f\u63cf\u8ff0"},{"location":"build-provider/definition/isolate-relationship/#_2","text":"\u8981\u4e86\u89e3\u5b9e\u4f8b\u95f4\u7684\u9694\u79bb\u5c42\u6b21\uff0c\u9996\u5148\u9700\u8981\u4e86\u89e3ServiceComb\u5b9a\u4e49\u7684\u4e00\u4e2a\u4f53\u7cfb\u5b8c\u5907\u7684\u5fae\u670d\u52a1\u7cfb\u7edf\u7ed3\u6784\uff1a \u5728\u5fae\u670d\u52a1\u7cfb\u7edf\u7ed3\u6784\u4e2d\uff0c\u9876\u5c42\u662f\u201c\u9879\u76ee\u201d\uff0c\u5728\u9879\u76ee\u4e0b\u5206\u4e3a\u591a\u4e2a\u79df\u6237\uff0c\u79df\u6237\u4e2d\u5305\u542b\u591a\u4e2a\u5e94\u7528\uff0c\u800c\u6bcf\u4e2a\u5e94\u7528\u7531\u5305\u542b\u591a\u4e2a\u73af\u5883\uff0c\u5373\u6d4b\u8bd5\u548c\u751f\u4ea7\u73af\u5883\u53ef\u4ee5\u5206\u5f00\u3002\u5728\u67d0\u4e2a\u7279\u5b9a\u5e94\u7528\u7684\u7279\u5b9a\u73af\u5883\u4e2d\uff0c\u5305\u542b\u591a\u4e2a\u5fae\u670d\u52a1\uff0c\u800c\u4e00\u4e2a\u5fae\u670d\u52a1\u53c8\u53ef\u4ee5\u540c\u65f6\u5b58\u5728\u591a\u4e2a\u7248\u672c\u3002\u4ee5\u4e0a\uff0c\u662f\u6240\u6709\u9759\u6001\u5143\u6570\u636e\u7684\u8303\u7574\uff0c\u67d0\u4e2a\u7279\u5b9a\u670d\u52a1\u7684\u7279\u5b9a\u7248\u672c\u5219\u5305\u542b\u591a\u4e2a\u5728\u8fd0\u884c\u65f6\u6ce8\u518c\u4e0a\u6765\u7684\u5fae\u670d\u52a1\u5b9e\u4f8b\uff0c\u56e0\u4e3a\u670d\u52a1\u5b9e\u4f8b\u7684\u4fe1\u606f\u5728\u8fd0\u884c\u65f6\u968f\u7740\u7cfb\u7edf\u7684\u4f38\u7f29\u3001\u6545\u969c\u7b49\u539f\u56e0\u662f\u52a8\u6001\u53d8\u5316\u7684\uff0c\u6240\u4ee5\u670d\u52a1\u5b9e\u4f8b\u7684\u8def\u7531\u4fe1\u606f\u53c8\u4e3a\u52a8\u6001\u6570\u636e\u3002\u901a\u8fc7\u5206\u5c42\u7ba1\u7406\u5fae\u670d\u52a1\u7684\u8fd9\u4e9b\u6570\u636e\uff0c\u4e5f\u5c31\u81ea\u7136\u800c\u7136\u7684\u5b9e\u73b0\u4e86\u5b9e\u4f8b\u4e4b\u95f4\u7684\u903b\u8f91\u9694\u79bb\u3002","title":"\u5fae\u670d\u52a1\u5b9e\u4f8b\u5206\u5c42\u7ba1\u7406"},{"location":"build-provider/definition/isolate-relationship/#_3","text":"ServiceComb\u652f\u6301\u81ea\u5b9a\u4e49\u5206\u5c42\u914d\u7f6e\uff0c\u6ee1\u8db3\u7528\u6237\u7684\u5b9e\u4f8b\u5206\u5c42\u7ba1\u7406\u9700\u6c42\uff0c\u4ee5\u4e0b\u662f\u5177\u4f53\u914d\u7f6e\u8bf4\u660e\u3002 \u5e94\u7528ID \u901a\u8fc7APPLICATIOIN_ID\u6765\u5b9a\u4e49\uff0c\u7f3a\u7701\u503c\u4e3adefault\u3002\u5fae\u670d\u52a1\u5728\u53d1\u73b0\u5b9e\u4f8b\u7684\u65f6\u5019\uff0c\u7f3a\u7701\u53ea\u80fd\u591f\u88ab\u76f8\u540cAPPLICATIOIN_ID\u4e0b\u7684\u6d88\u8d39\u8005\u53d1\u73b0\u3002 Domain\u540d\u79f0 \u901a\u8fc7cse.config.client.domainName\u6765\u5b9a\u4e49\uff0c\u7f3a\u7701\u503c\u4e3adefault\u3002\u4f5c\u4e3a\u5fae\u670d\u52a1\u63d0\u4f9b\u8005\uff0c\u7528\u4e8e\u8868\u660e\u81ea\u8eab\u6240\u5c5e\u79df\u6237\u4fe1\u606f\u3002\u5fae\u670d\u52a1\u5728\u53d1\u73b0\u5b9e\u4f8b\u7684\u65f6\u5019\uff0c\u53ea\u80fd\u88ab\u76f8\u540c\u79df\u6237\u4e0b\u7684\u6d88\u8d39\u8005\u53d1\u73b0\u3002 \u6570\u636e\u4e2d\u5fc3\u4fe1\u606f \u6570\u636e\u4e2d\u5fc3\u5305\u62ec3\u4e2a\u5c5e\u6027\uff1acse.datacenter.name\uff0c cse.datacenter.region, cse.datacenter.availableZone\u3002\u6570\u636e\u4e2d\u5fc3\u4fe1\u606f\u4e0d\u63d0\u4f9b\u9694\u79bb\u80fd\u529b\uff0c\u5fae\u670d\u52a1\u53ef\u4ee5\u53d1\u73b0\u5176\u4ed6\u6570\u636e\u4e2d\u5fc3\u7684\u5b9e\u4f8b\u3002\u4f46\u662f\u53ef\u4ee5\u901a\u8fc7\u542f\u7528\u5b9e\u4f8b\u4eb2\u548c\u6027\uff0c\u6765\u4f18\u5148\u5f80\u6307\u5b9a\u7684\u533a\u57df\u6216\u8005Zone\u53d1\u6d88\u606f\uff1a cse: loadbalance: serverListFilters: zoneaware serverListFilter: zoneaware: className: org.apache.servicecomb.loadbalance.filter.ZoneAwareServerListFilterExt \u8fd9\u6837\u914d\u7f6e\u540e\uff0c\u5ba2\u6237\u7aef\u5728\u8def\u7531\u7684\u65f6\u5019\uff0c\u4f1a\u4f18\u5148\u5c06\u8bf7\u6c42\u8f6c\u53d1\u5230zone/region\u90fd\u76f8\u540c\u7684\u5b9e\u4f8b\uff0c\u7136\u540e\u662fregion\u76f8\u540c\uff0c\u4f46zone\u4e0d\u76f8\u540c\u7684\u5b9e\u4f8b\uff0c\u90fd\u4e0d\u76f8\u540c\u7684\u65f6\u5019\uff0c\u5219\u6309\u7167\u8def\u7531\u89c4\u5219\u9009\u62e9\u4e00\u4e2a\u3002\u4eb2\u548c\u6027\u4e0d\u662f\u903b\u8f91\u9694\u79bb\uff0c\u53ea\u8981\u5b9e\u4f8b\u4e4b\u95f4\u7f51\u7edc\u662f\u8054\u901a\u7684\uff0c\u90a3\u4e48\u90fd\u6709\u53ef\u80fd\u8bbf\u95ee\u5230\uff1b\u5982\u679c\u7f51\u7edc\u4e0d\u901a\uff0c\u5219\u4f1a\u8bbf\u95ee\u5931\u8d25\u3002 \u73af\u5883\u4fe1\u606f \u5728yaml\u6587\u4ef6\u91cc\u901a\u8fc7service_description.environment\u6765\u914d\u7f6e\uff0c\u540c\u65f6\u652f\u6301\u901a\u8fc7\u73af\u5883\u53d8\u91cfSERVICECOMB_ENV\u914d\u7f6e\uff0c\u4ec5\u652f\u6301\u4ee5\u4e0b\u679a\u4e3e\u503c development,testing,acceptance,production\uff0c\u7f3a\u7701\u503c\u4e3a\"\"(\u7a7a)\u3002\u5fae\u670d\u52a1\u5728\u53d1\u73b0\u5b9e\u4f8b\u7684\u65f6\u5019\uff0c\u7f3a\u7701\u53ea\u80fd\u591f\u88ab\u76f8\u540cenvironment\u4e0b\u7684\u6d88\u8d39\u8005\u53d1\u73b0\u3002 service_description: environment: production","title":"\u9694\u79bb\u5c42\u6b21\u8bf4\u660e"},{"location":"build-provider/definition/isolate-relationship/#_4","text":"\u534e\u4e3a\u516c\u6709\u4e91\u6709\u7c7b\u4f3c\u7684\u6982\u5ff5\uff0c\u5e94\u7528\u3001\u79df\u6237\u3001Project\u3001Cluster\u7b49\uff0c\u5728\u5b9e\u9645\u5e94\u7528\u7684\u65f6\u5019\uff0c\u53ef\u4ee5\u5206\u522b\u5bf9\u5e94\u5230ServiceComb\u7684\u5e94\u7528\u3001\u79df\u6237\u3001Domain\u3001Zone\u7b49\u4fe1\u606f\u3002\u6bd4\u5982\u5728\u516c\u6709\u4e91\u4e0a\u5982\u679cCluster\u5171\u4eabProject\uff0c\u90a3\u4e48\u5c31\u53ef\u4ee5\u901a\u8fc7zone\u6765\u5bf9\u5e94Cluster\uff0c\u5b9e\u73b0\u96c6\u7fa4\u4e4b\u95f4\u7684\u4eb2\u548c\u6027\u8bbf\u95ee\u3002","title":"\u4e0e\u534e\u4e3a\u516c\u6709\u4e91\u6982\u5ff5\u7684\u5bf9\u5e94\u5173\u7cfb"},{"location":"build-provider/definition/service-definition/","text":"Service Definition Concept Description A service definition identifies a microservice. It defines the service name, version, and the application that the service belongs to. The service definition can also contain extended information defining the attribute metadata of a service. Scenario To define a new microservice or modify its basic information, you may need to create and modify service definitions. Configuration This section describe the following configration items related to the microservice.yaml file in the src\\main\\resources\\ directory. Configuration on Item Default Range Mandatory Description Remarks APPLICATION_ID - - Yes Indicates an application name. - service_description.name - - Yes Indicates a microservice name The microservice name should be unique within an application. The name can contain digits, uppercase and lowercase letters, hyphens(-), underscores(_), and periods(.); and can neither start nor end with punctuations. The naming rule is as follows: ^[a-zA-Z0-9]+$|^[a-zA-Z0-9][a-zA-Z0-9_-.]*[a-zA-Z0-9]$. service_description.version - - Yes Indicates a service version. - service_description.properties - - No Configures microservice metadata(in the microservice.yaml file). - service_description.propertyExtendedClass - - No Configures microservice metadata(through the PropertyExtended API). The configurations returned through the API will overwrite those with the same keys in the configuration file. instance_description.properties - - No Configures instance metadata(in the microservice.yaml file) instance_description.propertyExtendedClass - - No Configures microservice metadata(through the PropertyExtended API). The configurations returned through the API will overwrite thos with the same keys in the configuration file. NOTE\uff1a - The metadata of a service is registered to the service center with the service. It is changed together with the service version. Changing metadata in the service center will keep the version unchanged. - By default, one microservice can be called by only one APPLICATION_ID. You can set allowCrossApp=true in microservice properties to access a microservice acroos APPLICATION_ID. Sample Code APPLICATION_ID: helloTest #Application name service_description: #Service description name: helloServer #Microservice name version: 0.0.1 #Service version properties: #Metadata allowCrossApp: false key1: value1 key2: value2 propertyExtendedClass: org.apache.servicecomb.serviceregistry.MicroServicePropertyExtendedStub instance_description: #Instance description properties: #Metadata key3: value3 propertyExtendedClass: org.apache.servicecomb.serviceregistry.MicroServicePropertyExtendedStub","title":"Service definition"},{"location":"build-provider/definition/service-definition/#service-definition","text":"","title":"Service Definition"},{"location":"build-provider/definition/service-definition/#concept-description","text":"A service definition identifies a microservice. It defines the service name, version, and the application that the service belongs to. The service definition can also contain extended information defining the attribute metadata of a service.","title":"Concept Description"},{"location":"build-provider/definition/service-definition/#scenario","text":"To define a new microservice or modify its basic information, you may need to create and modify service definitions.","title":"Scenario"},{"location":"build-provider/definition/service-definition/#configuration","text":"This section describe the following configration items related to the microservice.yaml file in the src\\main\\resources\\ directory. Configuration on Item Default Range Mandatory Description Remarks APPLICATION_ID - - Yes Indicates an application name. - service_description.name - - Yes Indicates a microservice name The microservice name should be unique within an application. The name can contain digits, uppercase and lowercase letters, hyphens(-), underscores(_), and periods(.); and can neither start nor end with punctuations. The naming rule is as follows: ^[a-zA-Z0-9]+$|^[a-zA-Z0-9][a-zA-Z0-9_-.]*[a-zA-Z0-9]$. service_description.version - - Yes Indicates a service version. - service_description.properties - - No Configures microservice metadata(in the microservice.yaml file). - service_description.propertyExtendedClass - - No Configures microservice metadata(through the PropertyExtended API). The configurations returned through the API will overwrite those with the same keys in the configuration file. instance_description.properties - - No Configures instance metadata(in the microservice.yaml file) instance_description.propertyExtendedClass - - No Configures microservice metadata(through the PropertyExtended API). The configurations returned through the API will overwrite thos with the same keys in the configuration file. NOTE\uff1a - The metadata of a service is registered to the service center with the service. It is changed together with the service version. Changing metadata in the service center will keep the version unchanged. - By default, one microservice can be called by only one APPLICATION_ID. You can set allowCrossApp=true in microservice properties to access a microservice acroos APPLICATION_ID.","title":"Configuration"},{"location":"build-provider/definition/service-definition/#sample-code","text":"APPLICATION_ID: helloTest #Application name service_description: #Service description name: helloServer #Microservice name version: 0.0.1 #Service version properties: #Metadata allowCrossApp: false key1: value1 key2: value2 propertyExtendedClass: org.apache.servicecomb.serviceregistry.MicroServicePropertyExtendedStub instance_description: #Instance description properties: #Metadata key3: value3 propertyExtendedClass: org.apache.servicecomb.serviceregistry.MicroServicePropertyExtendedStub","title":"Sample Code"},{"location":"catalog/build-consumer/","text":"Develop consumer with Rest Template RestTemplate is a RESTful API provided by the Spring framework. ServiceComb provides the implementation class for service calling Develop consumer with AsyncRestTemplate AsyncRestTemplate allows users to make asynchronous service calls. The logic is similar to restTemplate, except that the service is called asynchronously. Develop consumer with transparent RPC The transparent RPC allows users to make service calls like a local call through a simple java interface. Using Contracts When a consumer calls a service from a provider, the contract is required. The consumer can get the providers' contracts in 2 ways: get the providers' contract from off-line, then manually configure it in the project. Or, download the contract from the service center. Call Control Instance level fault isolation The instance-level fault isolation feature introduces the ability to isolate failed service instances by stopping sending request to them. Fallback strategy The fallback strategy allows user to specify the conditions under which the ServiceComb framework will terminate the requests. Rate limiting strategy The user uses the rate limiting policy on the consumer side to control the frequency of requests sent to the specified microservice. Fault injection The user uses fault injection on the consumer side to set the delay and error of the request sent to the specified microservice and its trigger probability.","title":"Build consumer"},{"location":"catalog/build-consumer/#develop-consumer-with-rest-template","text":"RestTemplate is a RESTful API provided by the Spring framework. ServiceComb provides the implementation class for service calling","title":"Develop consumer with Rest Template"},{"location":"catalog/build-consumer/#develop-consumer-with-asyncresttemplate","text":"AsyncRestTemplate allows users to make asynchronous service calls. The logic is similar to restTemplate, except that the service is called asynchronously.","title":"Develop consumer with AsyncRestTemplate"},{"location":"catalog/build-consumer/#develop-consumer-with-transparent-rpc","text":"The transparent RPC allows users to make service calls like a local call through a simple java interface.","title":"Develop consumer with transparent RPC"},{"location":"catalog/build-consumer/#using-contracts","text":"When a consumer calls a service from a provider, the contract is required. The consumer can get the providers' contracts in 2 ways: get the providers' contract from off-line, then manually configure it in the project. Or, download the contract from the service center.","title":"Using Contracts"},{"location":"catalog/build-consumer/#call-control","text":"","title":"Call Control"},{"location":"catalog/build-consumer/#instance-level-fault-isolation","text":"The instance-level fault isolation feature introduces the ability to isolate failed service instances by stopping sending request to them.","title":"Instance level fault isolation"},{"location":"catalog/build-consumer/#fallback-strategy","text":"The fallback strategy allows user to specify the conditions under which the ServiceComb framework will terminate the requests.","title":"Fallback strategy"},{"location":"catalog/build-consumer/#rate-limiting-strategy","text":"The user uses the rate limiting policy on the consumer side to control the frequency of requests sent to the specified microservice.","title":"Rate limiting strategy"},{"location":"catalog/build-consumer/#fault-injection","text":"The user uses fault injection on the consumer side to set the delay and error of the request sent to the specified microservice and its trigger probability.","title":"Fault injection"},{"location":"catalog/build-provider/","text":"Service Definition \u2022 Service definition information is the identity of the microservice, which defines which application the service belongs to, as well as the name and version. The service definition information may also have extension information for defining attribute metadata of the service. Defining Service Contracts \u2022 Service contract, which refers to the micro-service interface contract based on the OpenAPI specification, which is the definition of the interface between the server and the consumer. The java chassis provides two ways to define contracts: code first and contract first. Use implicit contract \u2022 The downgrade strategy is the exception handling strategy used by the microservice when the service request is abnormal. Using Swagger Annotations \u2022 Swagger provides a set of annotations to describe the interface contract. Users can use annotations to add descriptions of contracts to the code. ServiceComb supports some of these annotations. Developing microservices with SpringMVC \u2022 ServiceComb supports SpringMVC annotations, allowing the development of microservices using SpringMVC style. It is recommended to read the project in detail with reference to the project SpringMVC. Developing microservices with JAX-RS \u2022 ServiceComb supports developers using JAX-RS annotations to develop services using JAX-RS patterns. Developing microservices with transparent RPC \u2022 The transparent RPC development model is a development model based on interfaces and interfaces. Service developers do not need to use Spring MVC and JAX-RS annotations. interface definition and data type \u2022 ServiceComb-Java-Chassis suggests that the interface definition follows a simple principle: the interface definition is the interface usage specification, and you can identify how to call this interface without looking at the code implementation. It can be seen that this principle stands on the user side and is easier to use as a reference. ServiceComb will generate interface contracts based on interface definitions, interfaces that conform to this principle, and the generated contracts are also easy for users to read. Service Listening Address and Publishing Address \u2022 In JavaChassis, the listening and publishing addresses of the service are two separate concepts that can be configured independently: Listening address: refers to the address that the microservice instance listens to when it starts. This configuration item determines which IPs can be accessed by this IP. Publish address: refers to the address where the microservice instance is registered to the service center. Other microservice instances will obtain information about this instance through the service center and access the service instance based on the publication address, so this configuration item determines which IP other services actually use to access the service. Service Configuration \u2022 Load Balancing Policy \u2022 Limiting Policy \u2022 Downgrade Strategy \u2022 Parameters and Research","title":"Build provider"},{"location":"catalog/build-provider/#service-definition","text":"\u2022 Service definition information is the identity of the microservice, which defines which application the service belongs to, as well as the name and version. The service definition information may also have extension information for defining attribute metadata of the service.","title":"Service Definition"},{"location":"catalog/build-provider/#defining-service-contracts","text":"\u2022 Service contract, which refers to the micro-service interface contract based on the OpenAPI specification, which is the definition of the interface between the server and the consumer. The java chassis provides two ways to define contracts: code first and contract first.","title":"Defining Service Contracts"},{"location":"catalog/build-provider/#use-implicit-contract","text":"\u2022 The downgrade strategy is the exception handling strategy used by the microservice when the service request is abnormal.","title":"Use implicit contract"},{"location":"catalog/build-provider/#using-swagger-annotations","text":"\u2022 Swagger provides a set of annotations to describe the interface contract. Users can use annotations to add descriptions of contracts to the code. ServiceComb supports some of these annotations.","title":"Using Swagger Annotations"},{"location":"catalog/build-provider/#developing-microservices-with-springmvc","text":"\u2022 ServiceComb supports SpringMVC annotations, allowing the development of microservices using SpringMVC style. It is recommended to read the project in detail with reference to the project SpringMVC.","title":"Developing microservices with SpringMVC"},{"location":"catalog/build-provider/#developing-microservices-with-jax-rs","text":"\u2022 ServiceComb supports developers using JAX-RS annotations to develop services using JAX-RS patterns.","title":"Developing microservices with JAX-RS"},{"location":"catalog/build-provider/#developing-microservices-with-transparent-rpc","text":"\u2022 The transparent RPC development model is a development model based on interfaces and interfaces. Service developers do not need to use Spring MVC and JAX-RS annotations.","title":"Developing microservices with transparent RPC"},{"location":"catalog/build-provider/#interface-definition-and-data-type","text":"\u2022 ServiceComb-Java-Chassis suggests that the interface definition follows a simple principle: the interface definition is the interface usage specification, and you can identify how to call this interface without looking at the code implementation. It can be seen that this principle stands on the user side and is easier to use as a reference. ServiceComb will generate interface contracts based on interface definitions, interfaces that conform to this principle, and the generated contracts are also easy for users to read.","title":"interface definition and data type"},{"location":"catalog/build-provider/#service-listening-address-and-publishing-address","text":"\u2022 In JavaChassis, the listening and publishing addresses of the service are two separate concepts that can be configured independently: Listening address: refers to the address that the microservice instance listens to when it starts. This configuration item determines which IPs can be accessed by this IP. Publish address: refers to the address where the microservice instance is registered to the service center. Other microservice instances will obtain information about this instance through the service center and access the service instance based on the publication address, so this configuration item determines which IP other services actually use to access the service.","title":"Service Listening Address and Publishing Address"},{"location":"catalog/build-provider/#service-configuration","text":"\u2022 Load Balancing Policy \u2022 Limiting Policy \u2022 Downgrade Strategy \u2022 Parameters and Research","title":"Service Configuration"},{"location":"catalog/config/","text":"General configuration instructions Introduce the configuration hierarchy relationship and the usage of the configuration mechanism of ServiceComb-Java-Chassis.","title":"Config"},{"location":"catalog/config/#general-configuration-instructions","text":"Introduce the configuration hierarchy relationship and the usage of the configuration mechanism of ServiceComb-Java-Chassis.","title":"General configuration instructions"},{"location":"catalog/data-conform/","text":"","title":"Data conform"},{"location":"catalog/general-develop/","text":"Access Service Center The system realizes the discovery between services through the service center. During the service startup process, the service center is registered. When calling other services, the service center will query the instance information of other services, such as the access address, the protocol used, and other parameters. The service center supports the use of PULL and PUSH modes to notify instance changes. Application Performance Monitoring 1. The introduction of Metrics 2. The summary of statistical items 3. The usage Micro Service Call Chain The microservices architecture solves the problems of many single applications, but it also requires us to pay extra. Request processing latency due to network instability is one of the costs. In a single application, all modules run in the same process, so there is no inter-module interworking problem. However, in the micro-service architecture, services communicate through the network, so we have to deal with network-related issues such as delays, timeouts, network partitions, and so on. In addition, as the business expands its services, it is difficult to see how data flows through a spider-like complex service structure. How can we effectively monitor network latency and visualize data flow in services? Distributed call chain tracking is used to effectively monitor network latency for microservices and visualize data flow in microservices. Custom call chain management Distributed call chain tracking provides timing information for calls between services, but the link call information inside the service is equally important to the developer. If you can combine the two into one, you can provide a more complete call chain, which is easier to locate. Errors and potential performance issues. Local development and testing This section describes how to develop and debug consumer/provider applications locally on the developer side. For development service providers, please refer to the section 3 Development Service Providers. For development service consumers, please refer to 4 Development Service Consumers. Both the service provider and the consumer provider need to connect to the remote service center. For the development and debugging of local microservices, this section describes two ways to set up a local service center for local microservices debugging: Http Filter In some scenarios, the service uses http instead of https as the network transmission channel. In order to prevent the falsification or tampering request, the signature function of the http code stream between the consumer and the producer needs to be provided. File Upload File upload, currently supported in vertx rest channel and servlet rest. File uploads use the standard http form format, which interfaces directly with the browser's upload. Download Document File downloads are currently available in the vertx rest channel and servlet rest. Reactive Comparison and description between simple synchronization mode, nested synchronous call, pure Reactive mechanism, and hybrid Reactive mechanism. DNS Custom Configuration When a user uses a domain name to connect to a Huawei public cloud or a three-party system, you need to use the domain name resolution system. The domain name resolution mechanisms used in different systems and different frameworks may be different. Therefore, it is necessary to provide a unified configuration entry so that development and operation personnel can customize the DNS resolution mechanism without being completely subject to system configuration. Proxy settings As a developer, in a company development environment, it is possible to access the Internet through a corporate agent network. If you must also rely on online resources when debugging services, such as directly connecting to Huawei's shared cloud service center, you must configure the agent. Frame report version number In order to facilitate the management, using ServiceComb for development, the currently used ServiceComb version number will be reported to the service center, and the version number of other frameworks will be reported when other frameworks integrate ServiceComb. Cross-application call An application is a layer in the microservice instance isolation hierarchy, and an application contains multiple microservices. By default, only microservice instances of the same application are allowed to call each other. Custom Serialization and Deserialization Methods Due to the non-security of the HTTP protocol, data transmitted over the network can be easily monitored by various packet capture tools. In practical applications, services have high security requirements for sensitive data transmitted between applications or services. Such data requires special encryption protection (different services have different algorithm requirements), so that even if the content is intercepted, it can protect Sensitive data is not easily obtained. Using Context to pass control messages ServiceComb provides a Context to pass data between microservices. Context is a key/value pair and can only use data of type String. Since the Context is serialized into the json format and passed through the HTTP header, characters other than ASCII are not supported. Other characters require the developer to encode and pass the code. The Context is passed on the request chain in a single request and does not need to be reset. Functions such as the trace id of the access log are implemented based on this feature. return value serialization extension The current REST channel return value supports both application/json and text/plain formats, supports developer extensions and rewrites, service providers provide serialization capabilities through producer declarations, and service consumers specify return value serialization through the request's Accept header. By default, the data in application/json format is returned. CORS mechanism Cross-Origin Resource Sharing (CORS) allows Web servers to perform cross-domain access control, enabling browsers to more securely transfer data across domains. Obtaining the fuse and instance isolation alarm event information When the microservice is running or the instance isolation status changes, you need to listen to related events, get relevant information and process it.","title":"General develop"},{"location":"catalog/general-develop/#access-service-center","text":"The system realizes the discovery between services through the service center. During the service startup process, the service center is registered. When calling other services, the service center will query the instance information of other services, such as the access address, the protocol used, and other parameters. The service center supports the use of PULL and PUSH modes to notify instance changes.","title":"Access Service Center"},{"location":"catalog/general-develop/#application-performance-monitoring","text":"1. The introduction of Metrics 2. The summary of statistical items 3. The usage","title":"Application Performance Monitoring"},{"location":"catalog/general-develop/#micro-service-call-chain","text":"The microservices architecture solves the problems of many single applications, but it also requires us to pay extra. Request processing latency due to network instability is one of the costs. In a single application, all modules run in the same process, so there is no inter-module interworking problem. However, in the micro-service architecture, services communicate through the network, so we have to deal with network-related issues such as delays, timeouts, network partitions, and so on. In addition, as the business expands its services, it is difficult to see how data flows through a spider-like complex service structure. How can we effectively monitor network latency and visualize data flow in services? Distributed call chain tracking is used to effectively monitor network latency for microservices and visualize data flow in microservices.","title":"Micro Service Call Chain"},{"location":"catalog/general-develop/#custom-call-chain-management","text":"Distributed call chain tracking provides timing information for calls between services, but the link call information inside the service is equally important to the developer. If you can combine the two into one, you can provide a more complete call chain, which is easier to locate. Errors and potential performance issues.","title":"Custom call chain management"},{"location":"catalog/general-develop/#local-development-and-testing","text":"This section describes how to develop and debug consumer/provider applications locally on the developer side. For development service providers, please refer to the section 3 Development Service Providers. For development service consumers, please refer to 4 Development Service Consumers. Both the service provider and the consumer provider need to connect to the remote service center. For the development and debugging of local microservices, this section describes two ways to set up a local service center for local microservices debugging:","title":"Local development and testing"},{"location":"catalog/general-develop/#http-filter","text":"In some scenarios, the service uses http instead of https as the network transmission channel. In order to prevent the falsification or tampering request, the signature function of the http code stream between the consumer and the producer needs to be provided.","title":"Http Filter"},{"location":"catalog/general-develop/#file-upload","text":"File upload, currently supported in vertx rest channel and servlet rest. File uploads use the standard http form format, which interfaces directly with the browser's upload.","title":"File Upload"},{"location":"catalog/general-develop/#download-document","text":"File downloads are currently available in the vertx rest channel and servlet rest.","title":"Download Document"},{"location":"catalog/general-develop/#reactive","text":"Comparison and description between simple synchronization mode, nested synchronous call, pure Reactive mechanism, and hybrid Reactive mechanism.","title":"Reactive"},{"location":"catalog/general-develop/#dns-custom-configuration","text":"When a user uses a domain name to connect to a Huawei public cloud or a three-party system, you need to use the domain name resolution system. The domain name resolution mechanisms used in different systems and different frameworks may be different. Therefore, it is necessary to provide a unified configuration entry so that development and operation personnel can customize the DNS resolution mechanism without being completely subject to system configuration.","title":"DNS Custom Configuration"},{"location":"catalog/general-develop/#proxy-settings","text":"As a developer, in a company development environment, it is possible to access the Internet through a corporate agent network. If you must also rely on online resources when debugging services, such as directly connecting to Huawei's shared cloud service center, you must configure the agent.","title":"Proxy settings"},{"location":"catalog/general-develop/#frame-report-version-number","text":"In order to facilitate the management, using ServiceComb for development, the currently used ServiceComb version number will be reported to the service center, and the version number of other frameworks will be reported when other frameworks integrate ServiceComb.","title":"Frame report version number"},{"location":"catalog/general-develop/#cross-application-call","text":"An application is a layer in the microservice instance isolation hierarchy, and an application contains multiple microservices. By default, only microservice instances of the same application are allowed to call each other.","title":"Cross-application call"},{"location":"catalog/general-develop/#custom-serialization-and-deserialization-methods","text":"Due to the non-security of the HTTP protocol, data transmitted over the network can be easily monitored by various packet capture tools. In practical applications, services have high security requirements for sensitive data transmitted between applications or services. Such data requires special encryption protection (different services have different algorithm requirements), so that even if the content is intercepted, it can protect Sensitive data is not easily obtained.","title":"Custom Serialization and Deserialization Methods"},{"location":"catalog/general-develop/#using-context-to-pass-control-messages","text":"ServiceComb provides a Context to pass data between microservices. Context is a key/value pair and can only use data of type String. Since the Context is serialized into the json format and passed through the HTTP header, characters other than ASCII are not supported. Other characters require the developer to encode and pass the code. The Context is passed on the request chain in a single request and does not need to be reset. Functions such as the trace id of the access log are implemented based on this feature.","title":"Using Context to pass control messages"},{"location":"catalog/general-develop/#return-value-serialization-extension","text":"The current REST channel return value supports both application/json and text/plain formats, supports developer extensions and rewrites, service providers provide serialization capabilities through producer declarations, and service consumers specify return value serialization through the request's Accept header. By default, the data in application/json format is returned.","title":"return value serialization extension"},{"location":"catalog/general-develop/#cors-mechanism","text":"Cross-Origin Resource Sharing (CORS) allows Web servers to perform cross-domain access control, enabling browsers to more securely transfer data across domains.","title":"CORS mechanism"},{"location":"catalog/general-develop/#obtaining-the-fuse-and-instance-isolation-alarm-event-information","text":"When the microservice is running or the instance isolation status changes, you need to listen to related events, get relevant information and process it.","title":"Obtaining the fuse and instance isolation alarm event information"},{"location":"catalog/securety/","text":"","title":"Securety"},{"location":"catalog/security/","text":"Using TLS communication Users can enable TLS communication through simple configuration to ensure data transmission security. Use RSA certification Users can enable RSA authentication between services through simple configuration to ensure the security of the service interface. Detailed reference to public key authentication","title":"Security"},{"location":"catalog/security/#using-tls-communication","text":"Users can enable TLS communication through simple configuration to ensure data transmission security.","title":"Using TLS communication"},{"location":"catalog/security/#use-rsa-certification","text":"Users can enable RSA authentication between services through simple configuration to ensure the security of the service interface. Detailed reference to public key authentication","title":"Use RSA certification"},{"location":"catalog/service-package-run/","text":"Packaged in standalone mode A Standalone container that loads Spring with a simple Main method, because the service usually does not require the properties of a Web container such as Tomcat/JBoss, and there is no need to use the Web container to load the service. The microframework provides a standalone deployment run mode. The service container is just a simple Main method and loads a simple Spring container to expose the service. Packaged in WEB container mode If you need to load the microservice into the web container to start the runtime, you need to create a new servlet project wrapper. The servlet project, if necessary, can not write or write a small amount of boot code.","title":"Service package run"},{"location":"catalog/service-package-run/#packaged-in-standalone-mode","text":"A Standalone container that loads Spring with a simple Main method, because the service usually does not require the properties of a Web container such as Tomcat/JBoss, and there is no need to use the Web container to load the service. The microframework provides a standalone deployment run mode. The service container is just a simple Main method and loads a simple Spring container to expose the service.","title":"Packaged in standalone mode"},{"location":"catalog/service-package-run/#packaged-in-web-container-mode","text":"If you need to load the microservice into the web container to start the runtime, you need to create a new servlet project wrapper. The servlet project, if necessary, can not write or write a small amount of boot code.","title":"Packaged in WEB container mode"},{"location":"catalog/start/","text":"Glossary Micro Service System Architecture Install local development environment \u2022 Service definition information is the identity of the microservice, which defines which application the service belongs to, as well as the name and version. The service definition information may also have extensive information for defining attribute metadata of the service. Developing the first microservice Developers can quickly build a project in two ways: \u2022 Download the samples project. It is recommended to download the entire project and initialize it according to the example SpringMVC or JAX RS. \u2022 Generate projects with archetypes","title":"Start"},{"location":"catalog/start/#glossary","text":"","title":"Glossary"},{"location":"catalog/start/#micro-service-system-architecture","text":"","title":"Micro Service System Architecture"},{"location":"catalog/start/#install-local-development-environment","text":"\u2022 Service definition information is the identity of the microservice, which defines which application the service belongs to, as well as the name and version. The service definition information may also have extensive information for defining attribute metadata of the service.","title":"Install local development environment"},{"location":"catalog/start/#developing-the-first-microservice","text":"Developers can quickly build a project in two ways: \u2022 Download the samples project. It is recommended to download the entire project and initialize it according to the example SpringMVC or JAX RS. \u2022 Generate projects with archetypes","title":"Developing the first microservice"},{"location":"catalog/use-tool/","text":"","title":"Use tool"},{"location":"config/general-config/","text":"General configuration instructions Configuration source hierarchical relationship ServiceComb provides a hierarchical configuration mechanism. According to the priority, it is divided as below(the former is higher): Configuration Center (dynamic configuration) Java System Property (-D parameter) Environmental variables Configuration file Configuration file The configuration file is the microservice.yaml file on classpath by default. When the ServiceComb-Java-Chassis is booting up, the microservice.yaml files are loaded from the jar files and the directories on the hard disks. All of the configuration files are merged into a set of valid configurations. The configuration files on the hard disks has higher priority than those in the jar files. The priority can also be specified by the servicecomb-config-order item in the configuration files. Tips: Since the microservice.yaml file on the hard disk has a higher priority, the . directory can be added into the classpath of the executable jar package, so that a microservice.yaml file can be placed in the directory where the service jar package is located, to overwrite the configuration files in the jar package. The default name of the configuration files is \"microservice.yaml\". The additional configuration files can be added by specifying Java System Property, and the name of the configuration files can be changed in this way, too: Java System Property Variable Name Description servicecomb.configurationSource.additionalUrls List of configuration files, multiple full file names can be specified with the ',' as separator servicecomb.configurationSource.defaultFileName Default configuration file name Environmental variables On Linux, the . charactor cannot be contained into environment variable name. As a result, some configuration items cannot be specified into environment variables directly. As a solution, the . charactor can be replaced by _ , and the converted configuration item can be specified as environment variable. ServiceComb-Java-Chassis can map those converted configuration items to the original configuration items. For example, for the configration in microservice.yaml file: servicecomb: rest: address: 0.0.0.0:8080 We can specify servicecomb_rest_address=0.0.0.0:9090 in the environment variable to overwrite the server port as 9090. This mapping mechanism can also applied to other configuration levels. Configuration Center (dynamic configuration) The default implementation of the dynamic configuration is the config-cc client, which is connected to the configuration center. The configuration items are as follows: Variable Description servicecomb.config.client.refreshMode Application configuration refresh mode, 0 is config-center active push, 1 is client cycle pull, default is 0 servicecomb.config.client.refreshPort config-center push configured port servicecomb.config.client.tenantName Application tenant name servicecomb.config.client.serverUri config-center access address, the format is http(s)://{ip}:{port} , to separate multiple addresses with comma (optional, when cse.config.client.regUri is configured as This configuration item will take effect when empty)) servicecomb.config.client.refresh_interval the configuration refresh interval, the unit is millisecond, default value is 15000 Get configuration information in the program Developers use a consistent API to get the configuration, regardless of the configured storage path: DynamicDoubleProperty myprop = DynamicPropertyFactory.getInstance().getDoubleProperty(\"trace.handler.sampler.percent\", 0.1); The instance above shows a configuration item whose key is trace.handler.sampler.percent , with default value 0.1. Developers can specify the value of this item in the microservice.yaml file, environment variable, Java System Property or Configuration center. There is no need for the developers to consider where to get the configuration values, Java-Chassis will load the configurations from everywhere, and merge them into one set of configurations according to the priority rule mentioned above. For details, please refer to [API DOC] (https://netflix.github.io/archaius/archaius-core-javadoc/com/netflix/config/DynamicPropertyFactory.html) You can register for a callback to handle configuration changes: myprop.addCallback(new Runnable() { public void run() { // this method is invoked when the value of this configuration item is modified System.out.println(\"trace.handler.sampler.percent is changed!\"); } }); Performing configuration item mapping In some cases, we want to block the configuration of some of the open source components we use and provide our users with their own configuration items. In this case, you can define the mapping through mapping.yaml under the classpath: registry: client: serviceUrl: defaultZone: eureka.client.serviceUrl.defaultZone After the mapping is defined, the framework maps by default when the configuration is loaded, and the configuration items defined by us are mapped to the configuration items that the open source component can recognize.","title":"General config"},{"location":"config/general-config/#general-configuration-instructions","text":"","title":"General configuration instructions"},{"location":"config/general-config/#configuration-source-hierarchical-relationship","text":"ServiceComb provides a hierarchical configuration mechanism. According to the priority, it is divided as below(the former is higher): Configuration Center (dynamic configuration) Java System Property (-D parameter) Environmental variables Configuration file","title":"Configuration source hierarchical relationship"},{"location":"config/general-config/#configuration-file","text":"The configuration file is the microservice.yaml file on classpath by default. When the ServiceComb-Java-Chassis is booting up, the microservice.yaml files are loaded from the jar files and the directories on the hard disks. All of the configuration files are merged into a set of valid configurations. The configuration files on the hard disks has higher priority than those in the jar files. The priority can also be specified by the servicecomb-config-order item in the configuration files. Tips: Since the microservice.yaml file on the hard disk has a higher priority, the . directory can be added into the classpath of the executable jar package, so that a microservice.yaml file can be placed in the directory where the service jar package is located, to overwrite the configuration files in the jar package. The default name of the configuration files is \"microservice.yaml\". The additional configuration files can be added by specifying Java System Property, and the name of the configuration files can be changed in this way, too: Java System Property Variable Name Description servicecomb.configurationSource.additionalUrls List of configuration files, multiple full file names can be specified with the ',' as separator servicecomb.configurationSource.defaultFileName Default configuration file name","title":"Configuration file"},{"location":"config/general-config/#environmental-variables","text":"On Linux, the . charactor cannot be contained into environment variable name. As a result, some configuration items cannot be specified into environment variables directly. As a solution, the . charactor can be replaced by _ , and the converted configuration item can be specified as environment variable. ServiceComb-Java-Chassis can map those converted configuration items to the original configuration items. For example, for the configration in microservice.yaml file: servicecomb: rest: address: 0.0.0.0:8080 We can specify servicecomb_rest_address=0.0.0.0:9090 in the environment variable to overwrite the server port as 9090. This mapping mechanism can also applied to other configuration levels.","title":"Environmental variables"},{"location":"config/general-config/#configuration-center-dynamic-configuration","text":"The default implementation of the dynamic configuration is the config-cc client, which is connected to the configuration center. The configuration items are as follows: Variable Description servicecomb.config.client.refreshMode Application configuration refresh mode, 0 is config-center active push, 1 is client cycle pull, default is 0 servicecomb.config.client.refreshPort config-center push configured port servicecomb.config.client.tenantName Application tenant name servicecomb.config.client.serverUri config-center access address, the format is http(s)://{ip}:{port} , to separate multiple addresses with comma (optional, when cse.config.client.regUri is configured as This configuration item will take effect when empty)) servicecomb.config.client.refresh_interval the configuration refresh interval, the unit is millisecond, default value is 15000","title":"Configuration Center (dynamic configuration)"},{"location":"config/general-config/#get-configuration-information-in-the-program","text":"Developers use a consistent API to get the configuration, regardless of the configured storage path: DynamicDoubleProperty myprop = DynamicPropertyFactory.getInstance().getDoubleProperty(\"trace.handler.sampler.percent\", 0.1); The instance above shows a configuration item whose key is trace.handler.sampler.percent , with default value 0.1. Developers can specify the value of this item in the microservice.yaml file, environment variable, Java System Property or Configuration center. There is no need for the developers to consider where to get the configuration values, Java-Chassis will load the configurations from everywhere, and merge them into one set of configurations according to the priority rule mentioned above. For details, please refer to [API DOC] (https://netflix.github.io/archaius/archaius-core-javadoc/com/netflix/config/DynamicPropertyFactory.html) You can register for a callback to handle configuration changes: myprop.addCallback(new Runnable() { public void run() { // this method is invoked when the value of this configuration item is modified System.out.println(\"trace.handler.sampler.percent is changed!\"); } });","title":"Get configuration information in the program"},{"location":"config/general-config/#performing-configuration-item-mapping","text":"In some cases, we want to block the configuration of some of the open source components we use and provide our users with their own configuration items. In this case, you can define the mapping through mapping.yaml under the classpath: registry: client: serviceUrl: defaultZone: eureka.client.serviceUrl.defaultZone After the mapping is defined, the framework maps by default when the configuration is loaded, and the configuration items defined by us are mapped to the configuration items that the open source component can recognize.","title":"Performing configuration item mapping"},{"location":"config/inject-config/","text":"Configuration injection ServiceComb provides the ability to inject configuration attributes into Java object fields and wildcard support. A Java object can be a Java Bean or a class with a public field. Configure injection objects We first design two Java classes to inject configuration attributes to demonstrate scenarios where annotations are not used and where annotations are used. /* Use ServiceComb annotations */ @InjectProperties(prefix = \"root\") //Specify the prefix of the configuration attribute associated with the model public class ConfigWithAnnotation { /* The prefix attribute value \"override\" here overrides the prefix attribute value \"root\" labeled in the @InjectProperties annotation of the class definition. The keys attribute can be an array of strings and the lower the subscript of the array element, the higher the priority. Configuration attributes are searched by the attribute names in the following order until the configuration attributes that have been configured are found, then the search is stopped: 1)override.high 2)override.low */ @InjectProperty(prefix = \"override\", keys = {\"high\", \"low\"}) public String strValue; //Keys support wildcards and specify wildcards'input objects when configuration attributes are injected. @InjectProperty(keys = \"${key}.value\") public int intValue; //The wildcard's surrogate object can be a list of strings. Priority follows the strategy that the lower the subscript of array elements, the higher the priority. @InjectProperty(keys = \"${full-list}\") public float floatValue; //The keys attribute also supports multiple wildcards, with priority as follows: first, the priority of wildcards decreases from left to right, and then, if wildcards are substituted into List, the lower the index of elements in List, the higher the priority strategy. @InjectProperty(keys = \"${low-list}.a.${high-list}.b\") public long longValue; //Default values can be specified by the defaultValue attribute of the annotation. If the field is not associated with any configuration properties, the default values defined will take effect, otherwise the default values will be overwritten. @InjectProperty(defaultValue = \"abc\") public String strDef; } /* not use Service Comb annotations */ public class ConfigNoAnnotation { /* If the @InjectProperties and @InjectProperty annotations are not provided, the field name is used as the configuration property name by default. Note that class names do not function as prefixes. Here, the configuration property strValue is bound to the field */ public String strValue; } Execution injection We can execute injection with the following sample code\uff1a Inject configuration properties into objects without InjectProperties and InjectProperty annotations: ConfigNoAnnotation config = SCBEngine.getInstance().getPriorityPropertyManager().createConfigObject(ConfigNoAnnotation.class); Inject configuration properties into objects annotated with InjectProperties and InjectProperty : Inject the configuration property named root.k.value into the intValue field of a ConfigWithAnnotation object The longValue field of the ConfigWithAnnotation object is injected by looking up the configured configuration properties in the following order: root.low-1.a.high-1.b root.low-1.a.high-2.b root.low-2.a.high-1.b root.low-2.a.high-2.b The floatValue field of the ConfigWithAnnotation object is injected by looking up the configured configuration properties in the following order: root.l1-1 root.l1-2 ConfigWithAnnotation config = SCBEngine.getInstance().getPriorityPropertyManager().createConfigObject(ConfigWithAnnotation.class, \"key\", \"k\", \"low-list\", Arrays.asList(\"low-1\", \"low-2\"), \"high-list\", Arrays.asList(\"high-1\", \"high-2\"), \"full-list\", Arrays.asList(\"l1-1\", \"l1-2\") ); Finally, whether it is an annotation injection or not, you must explicitly reclaim the configuration injection object. priorityPropertyManager.unregisterConfigObject(config) Reference resources Refer to the sample code\uff1a https://github.com/apache/servicecomb-java-chassis/blob/master/foundations/foundation-config/src/test/java/org/apache/servicecomb/config/inject/TestConfigObjectFactory.java","title":"Configuration injection"},{"location":"config/inject-config/#configuration-injection","text":"ServiceComb provides the ability to inject configuration attributes into Java object fields and wildcard support. A Java object can be a Java Bean or a class with a public field.","title":"Configuration injection"},{"location":"config/inject-config/#configure-injection-objects","text":"We first design two Java classes to inject configuration attributes to demonstrate scenarios where annotations are not used and where annotations are used. /* Use ServiceComb annotations */ @InjectProperties(prefix = \"root\") //Specify the prefix of the configuration attribute associated with the model public class ConfigWithAnnotation { /* The prefix attribute value \"override\" here overrides the prefix attribute value \"root\" labeled in the @InjectProperties annotation of the class definition. The keys attribute can be an array of strings and the lower the subscript of the array element, the higher the priority. Configuration attributes are searched by the attribute names in the following order until the configuration attributes that have been configured are found, then the search is stopped: 1)override.high 2)override.low */ @InjectProperty(prefix = \"override\", keys = {\"high\", \"low\"}) public String strValue; //Keys support wildcards and specify wildcards'input objects when configuration attributes are injected. @InjectProperty(keys = \"${key}.value\") public int intValue; //The wildcard's surrogate object can be a list of strings. Priority follows the strategy that the lower the subscript of array elements, the higher the priority. @InjectProperty(keys = \"${full-list}\") public float floatValue; //The keys attribute also supports multiple wildcards, with priority as follows: first, the priority of wildcards decreases from left to right, and then, if wildcards are substituted into List, the lower the index of elements in List, the higher the priority strategy. @InjectProperty(keys = \"${low-list}.a.${high-list}.b\") public long longValue; //Default values can be specified by the defaultValue attribute of the annotation. If the field is not associated with any configuration properties, the default values defined will take effect, otherwise the default values will be overwritten. @InjectProperty(defaultValue = \"abc\") public String strDef; } /* not use Service Comb annotations */ public class ConfigNoAnnotation { /* If the @InjectProperties and @InjectProperty annotations are not provided, the field name is used as the configuration property name by default. Note that class names do not function as prefixes. Here, the configuration property strValue is bound to the field */ public String strValue; }","title":"Configure injection objects"},{"location":"config/inject-config/#execution-injection","text":"We can execute injection with the following sample code\uff1a Inject configuration properties into objects without InjectProperties and InjectProperty annotations: ConfigNoAnnotation config = SCBEngine.getInstance().getPriorityPropertyManager().createConfigObject(ConfigNoAnnotation.class); Inject configuration properties into objects annotated with InjectProperties and InjectProperty : Inject the configuration property named root.k.value into the intValue field of a ConfigWithAnnotation object The longValue field of the ConfigWithAnnotation object is injected by looking up the configured configuration properties in the following order: root.low-1.a.high-1.b root.low-1.a.high-2.b root.low-2.a.high-1.b root.low-2.a.high-2.b The floatValue field of the ConfigWithAnnotation object is injected by looking up the configured configuration properties in the following order: root.l1-1 root.l1-2 ConfigWithAnnotation config = SCBEngine.getInstance().getPriorityPropertyManager().createConfigObject(ConfigWithAnnotation.class, \"key\", \"k\", \"low-list\", Arrays.asList(\"low-1\", \"low-2\"), \"high-list\", Arrays.asList(\"high-1\", \"high-2\"), \"full-list\", Arrays.asList(\"l1-1\", \"l1-2\") ); Finally, whether it is an annotation injection or not, you must explicitly reclaim the configuration injection object. priorityPropertyManager.unregisterConfigObject(config)","title":"Execution injection"},{"location":"config/inject-config/#reference-resources","text":"Refer to the sample code\uff1a https://github.com/apache/servicecomb-java-chassis/blob/master/foundations/foundation-config/src/test/java/org/apache/servicecomb/config/inject/TestConfigObjectFactory.java","title":"Reference resources"},{"location":"edge/by-servicecomb-sdk/","text":"Using Edge Service for Edge Services Edge Service is the JAVA gateway service development framework provided by ServiceComb. As the external interface of the entire microservice system, the Edge Service provides services to end users, accesses RESTful requests, and forwards them to internal microservices. The Edge Service is provided in the form of a development framework. Developers can easily build an Edge Service service and define routing and forwarding rules with a simple configuration. At the same time, Edge Service supports powerful expansion capabilities, and services such as service mapping, request parsing, encryption and decryption, and authentication can be extended. The Edge Service itself is also a microservice that is subject to all microservice development rules. It can be deployed as a multi-instance, and the front-end uses a load balancing device for load distribution. It can also be deployed as a master and backup, and directly access user requests. Developers can plan according to the logic and service access and networking conditions carried by the Edge Service. Developing Edge Service Developing Edge Service is similar to developing a normal microservice. Developers can import [ServiceComb Edge Service Demo] (https://github.com/apache/incubator-servicecomb-java-chassis/tree/master/demo/demo -edge) Start. Building a project from scratch involves the following steps: Configure dependencies By adding edge-core dependencies to your project, you can start the Edge Service. When the Edge Service requests forwarding, it will go through the processing chain, so it can also join the dependencies of the relevant processing chain modules. The following example adds the load balancing processing chain. This is a must. <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>edge-core</artifactId> </dependency> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>handler-loadbalance</artifactId> </dependency> Define the startup class Just like developing a normal microservice, you can pull the service by loading Spring. public class EdgeMain { public static void main(String[] args) throws Exception { Log4jUtils.init(); BeanUtils.init(); } } Increase the configuration file microservie.yaml The Edge Service itself is also a microservice that follows the rules of microservice lookup and will register itself. Note that APPLICAIONT_ID is the same as the microservice that needs to be forwarded. In the following configuration, the address that the Edge Service listens to, the processing chain, and so on are specified. The auth processing chain is a custom processing chain in the DEMO project for implementing authentication. At the same time, the auth service itself, without going through this processing chain, is equivalent to not authenticating. APPLICATION_ID: edge service_description: name: edge version: 0.0.1 servicecomb: service: registry: address: http://127.0.0.1:30100 rest: address: 127.0.0.1:18080 handler: chain: Consumer: default: auth,loadbalance service: auth: loadbalance work process The workflow of the Edge Service is as follows, the blue background part is executed in the Eventloop thread, and the yellow background part: * If working in reactive mode, execute directly in the Eventloop thread * If working in thread pool mode, execute in the thread pool thread Custom routing rules The core job of using the Edge Service is to configure routing rules. The rules are different, and the rules are different. A routing rule consists of a series of AbstractEdgeDispatchers. The Edge Service provides several common Dispatchers that can be enabled through configuration. If these Dispatchers do not meet the needs of the business scenario, they can be customized. Using DefaultEdgeDispatcher DefaultEdgeDispatcher is a very simple and easy to manage Dispatcher. With this Dispatcher, users do not need to manage forwarding rules dynamically. It is very convenient to apply to actual business scenarios. This is also a recommended management mechanism. It contains the following configuration items: servicecomb: http: dispatcher: edge: default: enabled: true prefix: rest withVersion: true prefixSegmentCount: 1 Examples and meanings of these common configuration items are as follows: * [prefix=rest;withVersion=true;prefixSegmentCount=1] The URL provided by the microservice xService is: /xService/v1/abc, the address accessed by the Edge is /rest/xService/v1/abc, and the request is only forwarded to [1.0 .0-2.0.0) version of the microservice instance. * [prefix=rest;withVersion=true;prefixSegmentCount=2] The URL provided by the microservice xService is: /v1/abc, the address accessed by the Edge is /rest/xService/v1/abc, and the request is only forwarded to [1.0.0] -2.0.0) version of the microservice instance. * [prefix=rest;withVersion=true;prefixSegmentCount=3] The URL provided by the microservice xService is: /abc, the address accessed by Edge is /rest/xService/v1/abc, and the request is forwarded only to [1.0.0-2.0] .0) version of the microservice instance. * [prefix=rest;withVersion=false;prefixSegmentCount=1] The URL provided by the microservice xService is: /xService/v1/abc, the address accessed by the Edge is /rest/xService/v1/abc, and the request may be forwarded to any micro Service instance. * [prefix=rest;withVersion=false;prefixSegmentCount=2] The URL provided by the microservice xService is: /v1/abc, the address accessed by Edge is /rest/xService/v1/abc, and the request may be forwarded to any microservice. Example. * [prefix=rest;withVersion=false;prefixSegmentCount=2] The URL provided by the microservice xService is: /abc, the address accessed by the Edge is /rest/xService/abc, and the request may be forwarded to any microservice instance. The withVersion configuration item provides a client grayscale rule that allows the client to specify which server version to access. The Edge Service also includes the ability to route based on interface compatibility automatically, and requests are forwarded to instances that contain the interface. Assume that a microservice, compatibility plan for all high versions must be compatible with the lower version, deploy the following version of the instance: 1.0.0, provides operation1 1.1.0, provided operation1, operation2 When Edge Service forwards operation1, it automatically uses the rule of 1.0.0+ to filter the instance. When Edge Service forwards operation2, it automatically uses the rules of 1.1.0+ to filter instances. The above process does not require any intervention and is fully automated to avoid forwarding the new version of the operation to the instance of the old version. Using URLMappedEdgeDispatcher URLMappedEdgeDispatcher allows users to configure mappings between URLs and microservices. It is very flexible to define which URLs are forwarded to which microservices. It contains the following configuration items: servicecomb: http: dispatcher: edge: url: enabled: true mappings: businessV1: prefixSegmentCount: 1 path: \"/url/business/v1/.*\" microserviceName: business versionRule: 1.0.0-2.0.0 businessV2: prefixSegmentCount: 1 path: \"/url/business/v2/.*\" microserviceName: business versionRule: 2.0.0-3.0.0 The meaning of the businessV1 configuration item is that the request with the request path of /usr/business/v1/. is forwarded to the microservice of business and only forwarded to the instance with version number 1.0.0-2.0.0 (excluding 2.0). .0). The URL when forwarding is /business/v1/. . Path uses the JDK regular expression, and you can view the description of the Pattern class. prefixSegmentCount indicates the number of URL segments of the prefix, and the prefix is not included in the forwarded URL path. Three forms of versionRule can be specified. 2.0.0-3.0.0 indicates the version range, including 2.0.0, but does not contain 3.0.0; 2.0.0+ indicates a version greater than 2.0.0, including 2.0.0; 2.0.0 means forwarding only to 2.0.0 version. 2, 2.0 is equivalent to 2.0.0. As can be seen from the above configuration, URLMappedEdgeDispatcher also supports client grayscale. Of course, there will be more configuration items than DefaultEdgeDispatcher. The URLMappedEdgeDispatcher supports dynamic configuration modification of the configuration center to adjust routing rules. Custom Dispatcher Customizing the Dispatcher involves two steps: Implement AbstractEdgeDispatcher Release via SPI: add the file META-INF/services/org.apache.servicecomb.transport.rest.vertx.VertxHttpDispatcher and write the implementation class Detailed code details can be found in the following section \"DEMO Functional Description\". Developers can also refer to the Code such as DefaultEdgeDispatcher to define their Dispatcher. Perform authentication and other business processing Through the Edge Service workflow, you can see that the Edge Service features can be extended in a variety of ways, including Dispatcher, HttpServerFilter, Handler, HttpClientFilter, and more. More common and straightforward is to extend through Handler. DEMO shows how to implement authentication through Handler extensions. Detailed code details can be found in the following section \"DEMO Functional Description\". Deployment example Operating mode reactive (default) The Edge Service works by default in the high-performance reactive mode. This mode requires that the business code working in the Edge Service forwarding process cannot have any blocking operations, including: Remote synchronization calls, such as an asynchronous query database, synchronous call microservices, or synchronous query remote cache, etc. any sleep call any wait call Oversized loop The underlying Edge Service is based on netty's vertx. The above constraint is netty's reactive mode constraint. Thread Pool If the business model cannot meet the reactive requirements, you need to use the thread pool mode. In this case, you need to configure it in the microservice.yaml of the Edge Service: servicecomb: executors: default: servicecomb.executor.groupThreadPool Here servicecomb.executor.groupThreadPool is the beanId of the spring bean corresponding to the default thread pool built into ServiceComb; the service can customize its thread pool and declare it as a bean whose beanId can also be configured here. DEMO Function Description Please refer to the edge service demo on GitHub: https://github.com/ServiceComb/ServiceComb-Java-Chassis/tree/master/demo/demo-edge The demo contains the following projects: authentication: microservice: authentication server edge-service hiboard-business-1.0.0 microservices: business, version 1.0.0, operation add hiboard-business-1.1.0 microservices: business, version 1.1.0, operation add/dec hiboard-business-2.0.0 microservices: business, version 2.0.0, operation add/dec hiboard-consumer as a normal httpclient, not a servicecomb consumer hiboard-model non-micro service, just some public models Access different versions of microservices through edge-service and confirm that the correct instance handles them. 1.Register Dispatcher Implement the interface org.apache.servicecomb.transport.rest.vertx.VertxHttpDispatcher, or inherit from org.apache.servicecomb.edge.core.AbstractEdgeDispatcher to implement your own dispatcher function. The implementation class is registered to the system through the Java standard SPI mechanism. Dispatcher needs to implement 2 methods: getOrder Dispatcher needs to inject routing rules into vertx, and routing rules have a priority order relationship. All Dispatchers in the system are sorted according to the return value of getOrder from small to large and initialized in order. If the GetOrder return values the two Dispatchers are the same, the order of the two is unpredictable. init The init method is included in the io.vertx.ext.web.The router in the vertx framework. You need to customize the routing rules through this object. You can specify the url that meets the requirements, whether you need to process the cookie, whether you need to handle the body, which custom method to use to process the received request, etc. For more details on routing rules, please refer to the official vertx documentation: [vertx routing mechanism] (http://vertx.io/docs/vertx-web/java/#_routing_by_exact_path) prompt: _ Multiple Dispatchers can set routing rules to cover the same url. _ _Assuming Dispatcher A and B can both handle the same url, and A has a higher priority, then: _ _ If A is processed, neither responding nor calling RoutingContext.next(), it is a bug, this request is hanged _ _ If A is processed and then calling RoutingContext.next(), the request will be transferred to B. 2. Forwarding request When registering a route, it specifies which method is used to process the request (the following method is used to refer to the method), and the forwarding logic is implemented in the onRequest. The method prototype is: void onRequest(RoutingContext context) The system encapsulates org.apache.servicecomb.edge.core.EdgeInvocation to implement forwarding. At least the following parameters need to be prepared: microserviceName, the business makes its own rules, can be passed in the url, or according to the url search, etc. context, that is, the input of onRequest path, the url of the forwarding target httpServerFilters, the Dispatcher parent class has initialized member variables EdgeInvocation edgeInvocation = new EdgeInvocation(); edgeInvocation.init(microserviceName, context, path, httpServerFilters); edgeInvocation.edgeInvoke(); The edgeInvoke call is internally called and will be forwarded as a ServiceComb standard consumer. As a standard consumer, it means that the governance capabilities of all ServiceComb standards are valid here. 3. Setting compatibility rules Different services may have different compatibility plans, servicecomb default compatibility rules, and all new versions are required to be compatible with the old version. If this requirement is met, no special settings need to be made. There is also a typical plan: 1.0.0-2.0.0 is internally compatible, url is in the form of /microserviceName/v1/.... 2.0.0-3.0.0 is internally compatible, url is in the form of /microserviceName/v2/.... ...... Incompatible between major versions At this point, the developer needs to set compatibility rules for EdgeInvocation: private CompatiblePathVersionMapper versionMapper = new CompatiblePathVersionMapper(); \u2026\u2026 edgeInvocation.setVersionRule(versionMapper.getOrCreate(pathVersion).getVersionRule()); The role of versionMapper is to convert a string such as v1 or v2 to a compatibility rule such as 1.0.0-2.0.0 or 2.0.0-3.0.0. note: Incompatible interfaces can cause many problems. The java chassis requires that the higher version of the service is compatible with the lower version of the service, and only allows the addition of the interface to not allow the interface to be deleted. After adding an interface, you must increase the version number of the microservice. In the development phase, interfaces change frequently, and developers often forget this rule. When this constraint is broken, you need to clean up the service center microservices information and restart the microservices and Edge Service\\ (and other services that depend on the microservices). Otherwise, the request forwarding failure may occur. 4.Authentication The Edge Service is the boundary of the system and requires authentication logic for many requests. Based on the standard ServiceComb mechanism, this function can be implemented by the handler. The simplest code is as follows: public class AuthHandler implements Handler { private Auth auth; public AuthHandler() { auth = Invoker.createProxy(\"auth\", \"auth\", Auth.class); } \u2026\u2026 @Override public void handle(Invocation invocation, AsyncResponse asyncResp) throws Exception { if (!auth.auth(\"\")) { asyncResp.consumerFail(new InvocationException(Status.UNAUTHORIZED, (Object) \"auth failed\")); return; } LOGGER.debug(\"auth success.\"); invocation.next(asyncResp); } } Auth is the interface provided by the authentication microservice. Invoker.createProxy(\"auth\", \"auth\", Auth.class) is the underlying api of the consumer in the transparent RPC development mode, which is equivalent to @ReferenceRpc, but not Need to rely on the spring bean mechanism. The business completely defines the Auth interface, but here is just an example. After the Handler development is complete, configure it into the microservice.yaml of the edge service: servicecomb: handler: chain: Consumer: default: auth,\u2026\u2026 service: auth: \u2026\u2026 In this example, it means that the forwarding request to all microservices must be authenticated, but authentication is not required when calling the authentication microservice.","title":"Using Edge Service"},{"location":"edge/by-servicecomb-sdk/#using-edge-service-for-edge-services","text":"Edge Service is the JAVA gateway service development framework provided by ServiceComb. As the external interface of the entire microservice system, the Edge Service provides services to end users, accesses RESTful requests, and forwards them to internal microservices. The Edge Service is provided in the form of a development framework. Developers can easily build an Edge Service service and define routing and forwarding rules with a simple configuration. At the same time, Edge Service supports powerful expansion capabilities, and services such as service mapping, request parsing, encryption and decryption, and authentication can be extended. The Edge Service itself is also a microservice that is subject to all microservice development rules. It can be deployed as a multi-instance, and the front-end uses a load balancing device for load distribution. It can also be deployed as a master and backup, and directly access user requests. Developers can plan according to the logic and service access and networking conditions carried by the Edge Service.","title":"Using Edge Service for Edge Services"},{"location":"edge/by-servicecomb-sdk/#developing-edge-service","text":"Developing Edge Service is similar to developing a normal microservice. Developers can import [ServiceComb Edge Service Demo] (https://github.com/apache/incubator-servicecomb-java-chassis/tree/master/demo/demo -edge) Start. Building a project from scratch involves the following steps: Configure dependencies By adding edge-core dependencies to your project, you can start the Edge Service. When the Edge Service requests forwarding, it will go through the processing chain, so it can also join the dependencies of the relevant processing chain modules. The following example adds the load balancing processing chain. This is a must. <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>edge-core</artifactId> </dependency> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>handler-loadbalance</artifactId> </dependency> Define the startup class Just like developing a normal microservice, you can pull the service by loading Spring. public class EdgeMain { public static void main(String[] args) throws Exception { Log4jUtils.init(); BeanUtils.init(); } } Increase the configuration file microservie.yaml The Edge Service itself is also a microservice that follows the rules of microservice lookup and will register itself. Note that APPLICAIONT_ID is the same as the microservice that needs to be forwarded. In the following configuration, the address that the Edge Service listens to, the processing chain, and so on are specified. The auth processing chain is a custom processing chain in the DEMO project for implementing authentication. At the same time, the auth service itself, without going through this processing chain, is equivalent to not authenticating. APPLICATION_ID: edge service_description: name: edge version: 0.0.1 servicecomb: service: registry: address: http://127.0.0.1:30100 rest: address: 127.0.0.1:18080 handler: chain: Consumer: default: auth,loadbalance service: auth: loadbalance","title":"Developing Edge Service"},{"location":"edge/by-servicecomb-sdk/#work-process","text":"The workflow of the Edge Service is as follows, the blue background part is executed in the Eventloop thread, and the yellow background part: * If working in reactive mode, execute directly in the Eventloop thread * If working in thread pool mode, execute in the thread pool thread","title":"work process"},{"location":"edge/by-servicecomb-sdk/#custom-routing-rules","text":"The core job of using the Edge Service is to configure routing rules. The rules are different, and the rules are different. A routing rule consists of a series of AbstractEdgeDispatchers. The Edge Service provides several common Dispatchers that can be enabled through configuration. If these Dispatchers do not meet the needs of the business scenario, they can be customized.","title":"Custom routing rules"},{"location":"edge/by-servicecomb-sdk/#using-defaultedgedispatcher","text":"DefaultEdgeDispatcher is a very simple and easy to manage Dispatcher. With this Dispatcher, users do not need to manage forwarding rules dynamically. It is very convenient to apply to actual business scenarios. This is also a recommended management mechanism. It contains the following configuration items: servicecomb: http: dispatcher: edge: default: enabled: true prefix: rest withVersion: true prefixSegmentCount: 1 Examples and meanings of these common configuration items are as follows: * [prefix=rest;withVersion=true;prefixSegmentCount=1] The URL provided by the microservice xService is: /xService/v1/abc, the address accessed by the Edge is /rest/xService/v1/abc, and the request is only forwarded to [1.0 .0-2.0.0) version of the microservice instance. * [prefix=rest;withVersion=true;prefixSegmentCount=2] The URL provided by the microservice xService is: /v1/abc, the address accessed by the Edge is /rest/xService/v1/abc, and the request is only forwarded to [1.0.0] -2.0.0) version of the microservice instance. * [prefix=rest;withVersion=true;prefixSegmentCount=3] The URL provided by the microservice xService is: /abc, the address accessed by Edge is /rest/xService/v1/abc, and the request is forwarded only to [1.0.0-2.0] .0) version of the microservice instance. * [prefix=rest;withVersion=false;prefixSegmentCount=1] The URL provided by the microservice xService is: /xService/v1/abc, the address accessed by the Edge is /rest/xService/v1/abc, and the request may be forwarded to any micro Service instance. * [prefix=rest;withVersion=false;prefixSegmentCount=2] The URL provided by the microservice xService is: /v1/abc, the address accessed by Edge is /rest/xService/v1/abc, and the request may be forwarded to any microservice. Example. * [prefix=rest;withVersion=false;prefixSegmentCount=2] The URL provided by the microservice xService is: /abc, the address accessed by the Edge is /rest/xService/abc, and the request may be forwarded to any microservice instance. The withVersion configuration item provides a client grayscale rule that allows the client to specify which server version to access. The Edge Service also includes the ability to route based on interface compatibility automatically, and requests are forwarded to instances that contain the interface. Assume that a microservice, compatibility plan for all high versions must be compatible with the lower version, deploy the following version of the instance: 1.0.0, provides operation1 1.1.0, provided operation1, operation2 When Edge Service forwards operation1, it automatically uses the rule of 1.0.0+ to filter the instance. When Edge Service forwards operation2, it automatically uses the rules of 1.1.0+ to filter instances. The above process does not require any intervention and is fully automated to avoid forwarding the new version of the operation to the instance of the old version.","title":"Using DefaultEdgeDispatcher"},{"location":"edge/by-servicecomb-sdk/#using-urlmappededgedispatcher","text":"URLMappedEdgeDispatcher allows users to configure mappings between URLs and microservices. It is very flexible to define which URLs are forwarded to which microservices. It contains the following configuration items: servicecomb: http: dispatcher: edge: url: enabled: true mappings: businessV1: prefixSegmentCount: 1 path: \"/url/business/v1/.*\" microserviceName: business versionRule: 1.0.0-2.0.0 businessV2: prefixSegmentCount: 1 path: \"/url/business/v2/.*\" microserviceName: business versionRule: 2.0.0-3.0.0 The meaning of the businessV1 configuration item is that the request with the request path of /usr/business/v1/. is forwarded to the microservice of business and only forwarded to the instance with version number 1.0.0-2.0.0 (excluding 2.0). .0). The URL when forwarding is /business/v1/. . Path uses the JDK regular expression, and you can view the description of the Pattern class. prefixSegmentCount indicates the number of URL segments of the prefix, and the prefix is not included in the forwarded URL path. Three forms of versionRule can be specified. 2.0.0-3.0.0 indicates the version range, including 2.0.0, but does not contain 3.0.0; 2.0.0+ indicates a version greater than 2.0.0, including 2.0.0; 2.0.0 means forwarding only to 2.0.0 version. 2, 2.0 is equivalent to 2.0.0. As can be seen from the above configuration, URLMappedEdgeDispatcher also supports client grayscale. Of course, there will be more configuration items than DefaultEdgeDispatcher. The URLMappedEdgeDispatcher supports dynamic configuration modification of the configuration center to adjust routing rules.","title":"Using URLMappedEdgeDispatcher"},{"location":"edge/by-servicecomb-sdk/#custom-dispatcher","text":"Customizing the Dispatcher involves two steps: Implement AbstractEdgeDispatcher Release via SPI: add the file META-INF/services/org.apache.servicecomb.transport.rest.vertx.VertxHttpDispatcher and write the implementation class Detailed code details can be found in the following section \"DEMO Functional Description\". Developers can also refer to the Code such as DefaultEdgeDispatcher to define their Dispatcher.","title":"Custom Dispatcher"},{"location":"edge/by-servicecomb-sdk/#perform-authentication-and-other-business-processing","text":"Through the Edge Service workflow, you can see that the Edge Service features can be extended in a variety of ways, including Dispatcher, HttpServerFilter, Handler, HttpClientFilter, and more. More common and straightforward is to extend through Handler. DEMO shows how to implement authentication through Handler extensions. Detailed code details can be found in the following section \"DEMO Functional Description\".","title":"Perform authentication and other business processing"},{"location":"edge/by-servicecomb-sdk/#deployment-example","text":"","title":"Deployment example"},{"location":"edge/by-servicecomb-sdk/#operating-mode","text":"","title":"Operating mode"},{"location":"edge/by-servicecomb-sdk/#reactive-default","text":"The Edge Service works by default in the high-performance reactive mode. This mode requires that the business code working in the Edge Service forwarding process cannot have any blocking operations, including: Remote synchronization calls, such as an asynchronous query database, synchronous call microservices, or synchronous query remote cache, etc. any sleep call any wait call Oversized loop The underlying Edge Service is based on netty's vertx. The above constraint is netty's reactive mode constraint.","title":"reactive (default)"},{"location":"edge/by-servicecomb-sdk/#thread-pool","text":"If the business model cannot meet the reactive requirements, you need to use the thread pool mode. In this case, you need to configure it in the microservice.yaml of the Edge Service: servicecomb: executors: default: servicecomb.executor.groupThreadPool Here servicecomb.executor.groupThreadPool is the beanId of the spring bean corresponding to the default thread pool built into ServiceComb; the service can customize its thread pool and declare it as a bean whose beanId can also be configured here.","title":"Thread Pool"},{"location":"edge/by-servicecomb-sdk/#demo-function-description","text":"Please refer to the edge service demo on GitHub: https://github.com/ServiceComb/ServiceComb-Java-Chassis/tree/master/demo/demo-edge The demo contains the following projects: authentication: microservice: authentication server edge-service hiboard-business-1.0.0 microservices: business, version 1.0.0, operation add hiboard-business-1.1.0 microservices: business, version 1.1.0, operation add/dec hiboard-business-2.0.0 microservices: business, version 2.0.0, operation add/dec hiboard-consumer as a normal httpclient, not a servicecomb consumer hiboard-model non-micro service, just some public models Access different versions of microservices through edge-service and confirm that the correct instance handles them.","title":"DEMO Function Description"},{"location":"edge/by-servicecomb-sdk/#1register-dispatcher","text":"Implement the interface org.apache.servicecomb.transport.rest.vertx.VertxHttpDispatcher, or inherit from org.apache.servicecomb.edge.core.AbstractEdgeDispatcher to implement your own dispatcher function. The implementation class is registered to the system through the Java standard SPI mechanism. Dispatcher needs to implement 2 methods:","title":"1.Register Dispatcher"},{"location":"edge/by-servicecomb-sdk/#getorder","text":"Dispatcher needs to inject routing rules into vertx, and routing rules have a priority order relationship. All Dispatchers in the system are sorted according to the return value of getOrder from small to large and initialized in order. If the GetOrder return values the two Dispatchers are the same, the order of the two is unpredictable.","title":"getOrder"},{"location":"edge/by-servicecomb-sdk/#init","text":"The init method is included in the io.vertx.ext.web.The router in the vertx framework. You need to customize the routing rules through this object. You can specify the url that meets the requirements, whether you need to process the cookie, whether you need to handle the body, which custom method to use to process the received request, etc. For more details on routing rules, please refer to the official vertx documentation: [vertx routing mechanism] (http://vertx.io/docs/vertx-web/java/#_routing_by_exact_path) prompt: _ Multiple Dispatchers can set routing rules to cover the same url. _ _Assuming Dispatcher A and B can both handle the same url, and A has a higher priority, then: _ _ If A is processed, neither responding nor calling RoutingContext.next(), it is a bug, this request is hanged _ _ If A is processed and then calling RoutingContext.next(), the request will be transferred to B.","title":"init"},{"location":"edge/by-servicecomb-sdk/#2-forwarding-request","text":"When registering a route, it specifies which method is used to process the request (the following method is used to refer to the method), and the forwarding logic is implemented in the onRequest. The method prototype is: void onRequest(RoutingContext context) The system encapsulates org.apache.servicecomb.edge.core.EdgeInvocation to implement forwarding. At least the following parameters need to be prepared: microserviceName, the business makes its own rules, can be passed in the url, or according to the url search, etc. context, that is, the input of onRequest path, the url of the forwarding target httpServerFilters, the Dispatcher parent class has initialized member variables EdgeInvocation edgeInvocation = new EdgeInvocation(); edgeInvocation.init(microserviceName, context, path, httpServerFilters); edgeInvocation.edgeInvoke(); The edgeInvoke call is internally called and will be forwarded as a ServiceComb standard consumer. As a standard consumer, it means that the governance capabilities of all ServiceComb standards are valid here.","title":"2. Forwarding request"},{"location":"edge/by-servicecomb-sdk/#3-setting-compatibility-rules","text":"Different services may have different compatibility plans, servicecomb default compatibility rules, and all new versions are required to be compatible with the old version. If this requirement is met, no special settings need to be made. There is also a typical plan: 1.0.0-2.0.0 is internally compatible, url is in the form of /microserviceName/v1/.... 2.0.0-3.0.0 is internally compatible, url is in the form of /microserviceName/v2/.... ...... Incompatible between major versions At this point, the developer needs to set compatibility rules for EdgeInvocation: private CompatiblePathVersionMapper versionMapper = new CompatiblePathVersionMapper(); \u2026\u2026 edgeInvocation.setVersionRule(versionMapper.getOrCreate(pathVersion).getVersionRule()); The role of versionMapper is to convert a string such as v1 or v2 to a compatibility rule such as 1.0.0-2.0.0 or 2.0.0-3.0.0. note: Incompatible interfaces can cause many problems. The java chassis requires that the higher version of the service is compatible with the lower version of the service, and only allows the addition of the interface to not allow the interface to be deleted. After adding an interface, you must increase the version number of the microservice. In the development phase, interfaces change frequently, and developers often forget this rule. When this constraint is broken, you need to clean up the service center microservices information and restart the microservices and Edge Service\\ (and other services that depend on the microservices). Otherwise, the request forwarding failure may occur.","title":"3. Setting compatibility rules"},{"location":"edge/by-servicecomb-sdk/#4authentication","text":"The Edge Service is the boundary of the system and requires authentication logic for many requests. Based on the standard ServiceComb mechanism, this function can be implemented by the handler. The simplest code is as follows: public class AuthHandler implements Handler { private Auth auth; public AuthHandler() { auth = Invoker.createProxy(\"auth\", \"auth\", Auth.class); } \u2026\u2026 @Override public void handle(Invocation invocation, AsyncResponse asyncResp) throws Exception { if (!auth.auth(\"\")) { asyncResp.consumerFail(new InvocationException(Status.UNAUTHORIZED, (Object) \"auth failed\")); return; } LOGGER.debug(\"auth success.\"); invocation.next(asyncResp); } } Auth is the interface provided by the authentication microservice. Invoker.createProxy(\"auth\", \"auth\", Auth.class) is the underlying api of the consumer in the transparent RPC development mode, which is equivalent to @ReferenceRpc, but not Need to rely on the spring bean mechanism. The business completely defines the Auth interface, but here is just an example. After the Handler development is complete, configure it into the microservice.yaml of the edge service: servicecomb: handler: chain: Consumer: default: auth,\u2026\u2026 service: auth: \u2026\u2026 In this example, it means that the forwarding request to all microservices must be authenticated, but authentication is not required when calling the authentication microservice.","title":"4.Authentication"},{"location":"edge/nginx/","text":"Using confd and Nginx for edge services Concept Description confd Confd is a lightweight configuration management tool, source code: [https://github.com/kelseyhightower/confd] (https://github.com/kelseyhightower/confd), which stores configuration information in etcd, Consul, dynamodb, redis, and zookeeper. Confd periodically pulls the latest configuration from these storage nodes, then reloads the service and completes the configuration file update. Nginx Nginx (engine x) is a high-performance HTTP and reverse proxy server with load balancing capabilities. For details, please refer to [http://www.nginx.cn/doc/] (http://www.nginx.cn/doc/). The services introduced in this section mainly use the Nginx http proxy function. Scene Description The technology introduced in this section is to use nginx+confd as the edge service. At the same time, you can dock the service center in the Java Chassis microservices framework, and pull the service information from the service center to dynamically update the nginx configuration through confd. The implementation steps of using nginx+confd dynamic reverse proxy can be found in the article [http://www.cnblogs.com/Anker/p/6112022.html] (http://www.cnblogs.com/Anker/p/6112022. Html), this section mainly introduces how confd docks the service center of the Java Chassis framework. Docking Service Center The core of the technology introduced in this section is how to make confd get the service information of the service center. The service center opens the following interfaces for external calls: Method one: http call The service provider open http interface needs to add the tenant header information: \"X-Tenant-Name:tenantName\", and the tenameName is the tenant name. The default is default, for example, \"X-Tenant-Name: default\". Check the health status of the service center GET 127.0.0.1:30100/health Get all micro service information GET 127.0.0.1:30100/registry/v3/microservices Get the microservice information of the specified id First get the serviceId based on the microservice information GET 127.0.0.1:30100/registry/v3/existence?type=microservice&appId={appId}&serviceName={serviceName}&version={version} Obtain the microservice complete information according to the serviceId returned by the above interface. GET 127.0.0.1:30100/registry/v3/microservices/{serviceId} Get all instance information for the specified microservice ``` GET 127.0.0.1:30100/registry/v3/microservices/{serviceId}/instances Need to add in the header: \"X-ConsumerId: {serviceId}\". ``` Find micro service instance information ``` GET 127.0.0.1:30100/registry/v3/instances?appId={appId}&serviceName={serviceName}&version={version} Need to add in the header: \"X-ConsumerId: {serviceId}\". ``` Note: In actual development, please visit the actual service-center access address, and replace the variable of {} in the above url with a specific value. The data returned by http is in json format. Method 2: Use servicecomb open source code interface In the development of microservices applications, you only need to call the interface provided in the tool class RegistryUtil.java in the servicecomb framework code to get the information of the service center. The interface description is as follows: Get all micro service information java List<Microservice> getAllMicroservices(); Get the microservice unique identifier java String getMicroserviceId(String appId, String microserviceName, String versionRule); Query microservice static information based on microservice unique identifier java Microservice getMicroservice(String microserviceId); Query all micro service instance information based on multiple microservice unique identifiers java List<MicroserviceInstance> getMicroserviceInstance(String consumerId, String providerId); Query instance endpoints information by app+interface+version java List<MicroserviceInstance> findServiceInstance(String consumerId, String appId, String serviceName, String versionRule); Through the above http interface, information about the microservices of the service center and its instances can be obtained, thereby dynamically updating the nginx configuration through confd.","title":"Using confd and Nginx as edge services"},{"location":"edge/nginx/#using-confd-and-nginx-for-edge-services","text":"","title":"Using confd and Nginx for edge services"},{"location":"edge/nginx/#concept-description","text":"","title":"Concept Description"},{"location":"edge/nginx/#confd","text":"Confd is a lightweight configuration management tool, source code: [https://github.com/kelseyhightower/confd] (https://github.com/kelseyhightower/confd), which stores configuration information in etcd, Consul, dynamodb, redis, and zookeeper. Confd periodically pulls the latest configuration from these storage nodes, then reloads the service and completes the configuration file update.","title":"confd"},{"location":"edge/nginx/#nginx","text":"Nginx (engine x) is a high-performance HTTP and reverse proxy server with load balancing capabilities. For details, please refer to [http://www.nginx.cn/doc/] (http://www.nginx.cn/doc/). The services introduced in this section mainly use the Nginx http proxy function.","title":"Nginx"},{"location":"edge/nginx/#scene-description","text":"The technology introduced in this section is to use nginx+confd as the edge service. At the same time, you can dock the service center in the Java Chassis microservices framework, and pull the service information from the service center to dynamically update the nginx configuration through confd. The implementation steps of using nginx+confd dynamic reverse proxy can be found in the article [http://www.cnblogs.com/Anker/p/6112022.html] (http://www.cnblogs.com/Anker/p/6112022. Html), this section mainly introduces how confd docks the service center of the Java Chassis framework.","title":"Scene Description"},{"location":"edge/nginx/#docking-service-center","text":"The core of the technology introduced in this section is how to make confd get the service information of the service center. The service center opens the following interfaces for external calls:","title":"Docking Service Center"},{"location":"edge/nginx/#method-one-http-call","text":"The service provider open http interface needs to add the tenant header information: \"X-Tenant-Name:tenantName\", and the tenameName is the tenant name. The default is default, for example, \"X-Tenant-Name: default\". Check the health status of the service center GET 127.0.0.1:30100/health Get all micro service information GET 127.0.0.1:30100/registry/v3/microservices Get the microservice information of the specified id First get the serviceId based on the microservice information GET 127.0.0.1:30100/registry/v3/existence?type=microservice&appId={appId}&serviceName={serviceName}&version={version} Obtain the microservice complete information according to the serviceId returned by the above interface. GET 127.0.0.1:30100/registry/v3/microservices/{serviceId} Get all instance information for the specified microservice ``` GET 127.0.0.1:30100/registry/v3/microservices/{serviceId}/instances Need to add in the header: \"X-ConsumerId: {serviceId}\". ``` Find micro service instance information ``` GET 127.0.0.1:30100/registry/v3/instances?appId={appId}&serviceName={serviceName}&version={version} Need to add in the header: \"X-ConsumerId: {serviceId}\". ```","title":"Method one: http call"},{"location":"edge/nginx/#note-in-actual-development-please-visit-the-actual-service-center-access-address-and-replace-the-variable-of-in-the-above-url-with-a-specific-value-the-data-returned-by-http-is-in-json-format","text":"","title":"Note: In actual development, please visit the actual service-center access address, and replace the variable of {} in the above url with a specific value. The data returned by http is in json format."},{"location":"edge/nginx/#method-2-use-servicecomb-open-source-code-interface","text":"In the development of microservices applications, you only need to call the interface provided in the tool class RegistryUtil.java in the servicecomb framework code to get the information of the service center. The interface description is as follows: Get all micro service information java List<Microservice> getAllMicroservices(); Get the microservice unique identifier java String getMicroserviceId(String appId, String microserviceName, String versionRule); Query microservice static information based on microservice unique identifier java Microservice getMicroservice(String microserviceId); Query all micro service instance information based on multiple microservice unique identifiers java List<MicroserviceInstance> getMicroserviceInstance(String consumerId, String providerId); Query instance endpoints information by app+interface+version java List<MicroserviceInstance> findServiceInstance(String consumerId, String appId, String serviceName, String versionRule); Through the above http interface, information about the microservices of the service center and its instances can be obtained, thereby dynamically updating the nginx configuration through confd.","title":"Method 2: Use servicecomb open source code interface"},{"location":"edge/open-service/","text":"Open service capacity A large number of micro-service capabilities need to be opened to users and other external systems through the gateway. On the one hand, the gateway plays the role of collecting user requests, and also plays the role of authentication, authentication, flow control, and anti-attack. At the same time, because the gateway is a convergence point, it is easy to form a bottleneck of the service. Usually, a multi-level gateway mechanism is adopted. The external gateway provides the master and backup as well as the simple request forwarding function, and the middle layer implements authentication and other functions. Deploy. Common technologies and services that can be used for gateways include LVS, Nginx, Zuul, and others. ServiceComb also provides its gateway service, Edge Service. The Edge Service has built-in powerful routing policies, supports interface-level compatibility forwarding (grayscale publishing), embedded ServiceComb governance capabilities, and supports very flexible extension mechanisms.","title":"Intruductions"},{"location":"edge/open-service/#open-service-capacity","text":"A large number of micro-service capabilities need to be opened to users and other external systems through the gateway. On the one hand, the gateway plays the role of collecting user requests, and also plays the role of authentication, authentication, flow control, and anti-attack. At the same time, because the gateway is a convergence point, it is easy to form a bottleneck of the service. Usually, a multi-level gateway mechanism is adopted. The external gateway provides the master and backup as well as the simple request forwarding function, and the middle layer implements authentication and other functions. Deploy. Common technologies and services that can be used for gateways include LVS, Nginx, Zuul, and others. ServiceComb also provides its gateway service, Edge Service. The Edge Service has built-in powerful routing policies, supports interface-level compatibility forwarding (grayscale publishing), embedded ServiceComb governance capabilities, and supports very flexible extension mechanisms.","title":"Open service capacity"},{"location":"edge/zuul/","text":"Using zuul for edge services Concept Description API Gateway: The API Gateway is a server or a unique node that enters the system. The API Gateway encapsulates the architecture of the internal system and provides APIs to individual clients. Zuul Zuul is Netflix's JVM-based router and server-side load balancer, which can be used by Zuul to: Certification Insight pressure test Canary Test Dynamic routing Service migration Load shedding Safety Static phase response processing Active / passive traffic management This section focuses on using Zuul as an API Gateway in SpringBoot applications. For detailed functions of Zuul, please refer to the document [router and filter: Zuul] (https://springcloud.cc/spring-cloud-dalston.html#_router_and_filter_zuul). Scene Description Zuul is the API Gateway, which is to establish a Zuul Proxy application. All the microservice access portals are defined in the Proxy application, and different microservices are distinguished by using different prefixes (stripped). This section demonstrates Zuul's API Gateway functionality by creating a ZuulProxy SpringBoot application. Precautions The demos such as ZuulProxy and ZuulServer described in this section are based on SpringBoot and ServiceComb frameworks. For details, please refer to [using java chassis in Spring Boot] (../using-java-chassis-in-spring-boot/using-java-chassis-in-spring-boot.md). Launching Zuul Proxy This section describes how to launch a zuul proxy application as an API Gateway. Proceed as follows: Step 1 Add a dependency to the pom file: <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zuul</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> </dependency><dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>spring-boot-starter-discovery</artifactId> </dependency> Step 2 Add annotations to the SpringBoot main class: @SpringBootApplication @EnableServiceComb @EnableZuulProxy//Additional annotations public class ZuulMain{ public static void main(String[] args) throws Exception{ SpringApplication.run(ZuulMain.class, args); } } Step 3 Define the routing policy in the application.yml file: server: port: 8754 #api gateway service port zuul: routes: #route strategy discoveryServer: /myServer/** #route rule The red configuration item indicates that it can be configured according to the actual development environment. For detailed definition rules of the routing policy of zuul.routers, please refer to the official literature: [router and filter: Zuul] (https://springcloud.cc/spring-cloud-dalston.html#_router_and_filter_zuul), which can be more finely Control the route. Step 4 Define microservice properties in microservice.yaml: APPLICATION_ID: discoverytest #service ID service_description: name: discoveryGateway #service name version: 0.0.2 #service version number servicecomb: service: Registry: Address: http://127.0.0.1:30100 #Service registry address rest: address: 0.0.0.0:8082 # Service port, can not write Step 5 Run ZuulMain Application Using Zuul Proxy Before using the API Gateway made by Zuul, you must first start the microservice provider defined in zuul.routers. To develop a service provider, please refer to 3 Development Service Provider for the opening process. Pay attention to the following two points in the microservice.yaml file: APPLICATION_ID needs to be consistent in the definition defined in the zuul proxy. service_description.name needs to correspond to zuul.routers. An example is as follows: APPLICATION_ID: discoverytest # is consistent with zuul proxy service_description: name: discoveryServer #service name, corresponding to zuul.routers version: 0.0.2 servicecomb: service: registry: address: http://127.0.0.1:30100 #Service registry address rest: address: 0.0.0.0:8080 The API Gateway access is: [http://127.0.0.1:8754] (http://127.0.0.1:8754), all services defined in zuul.routers can be accessed through this access portal, access The rules are as follows: http://127.0.0.1:8754/myServer/*** This means that Http calls [http://127.0.0.1:8754/myServer/***] (http://127.0.0.1:8754/myServer/***) and will go to the discoveryServer service (for example: \"/myServer/101\" jumps to \"/101\" under the discoveryServer service) If there are multiple discoveryServer services in the service center (version is different), zuul uses the Ribbon policy to forward requests.","title":"Use zuul as edge services"},{"location":"edge/zuul/#using-zuul-for-edge-services","text":"","title":"Using zuul for edge services"},{"location":"edge/zuul/#concept-description","text":"","title":"Concept Description"},{"location":"edge/zuul/#api-gateway","text":"The API Gateway is a server or a unique node that enters the system. The API Gateway encapsulates the architecture of the internal system and provides APIs to individual clients.","title":"API Gateway:"},{"location":"edge/zuul/#zuul","text":"Zuul is Netflix's JVM-based router and server-side load balancer, which can be used by Zuul to: Certification Insight pressure test Canary Test Dynamic routing Service migration Load shedding Safety Static phase response processing Active / passive traffic management This section focuses on using Zuul as an API Gateway in SpringBoot applications. For detailed functions of Zuul, please refer to the document [router and filter: Zuul] (https://springcloud.cc/spring-cloud-dalston.html#_router_and_filter_zuul).","title":"Zuul"},{"location":"edge/zuul/#scene-description","text":"Zuul is the API Gateway, which is to establish a Zuul Proxy application. All the microservice access portals are defined in the Proxy application, and different microservices are distinguished by using different prefixes (stripped). This section demonstrates Zuul's API Gateway functionality by creating a ZuulProxy SpringBoot application.","title":"Scene Description"},{"location":"edge/zuul/#precautions","text":"The demos such as ZuulProxy and ZuulServer described in this section are based on SpringBoot and ServiceComb frameworks. For details, please refer to [using java chassis in Spring Boot] (../using-java-chassis-in-spring-boot/using-java-chassis-in-spring-boot.md).","title":"Precautions"},{"location":"edge/zuul/#launching-zuul-proxy","text":"This section describes how to launch a zuul proxy application as an API Gateway. Proceed as follows: Step 1 Add a dependency to the pom file: <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zuul</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> </dependency><dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>spring-boot-starter-discovery</artifactId> </dependency> Step 2 Add annotations to the SpringBoot main class: @SpringBootApplication @EnableServiceComb @EnableZuulProxy//Additional annotations public class ZuulMain{ public static void main(String[] args) throws Exception{ SpringApplication.run(ZuulMain.class, args); } } Step 3 Define the routing policy in the application.yml file: server: port: 8754 #api gateway service port zuul: routes: #route strategy discoveryServer: /myServer/** #route rule The red configuration item indicates that it can be configured according to the actual development environment. For detailed definition rules of the routing policy of zuul.routers, please refer to the official literature: [router and filter: Zuul] (https://springcloud.cc/spring-cloud-dalston.html#_router_and_filter_zuul), which can be more finely Control the route. Step 4 Define microservice properties in microservice.yaml: APPLICATION_ID: discoverytest #service ID service_description: name: discoveryGateway #service name version: 0.0.2 #service version number servicecomb: service: Registry: Address: http://127.0.0.1:30100 #Service registry address rest: address: 0.0.0.0:8082 # Service port, can not write Step 5 Run ZuulMain Application","title":"Launching Zuul Proxy"},{"location":"edge/zuul/#using-zuul-proxy","text":"Before using the API Gateway made by Zuul, you must first start the microservice provider defined in zuul.routers. To develop a service provider, please refer to 3 Development Service Provider for the opening process. Pay attention to the following two points in the microservice.yaml file: APPLICATION_ID needs to be consistent in the definition defined in the zuul proxy. service_description.name needs to correspond to zuul.routers. An example is as follows: APPLICATION_ID: discoverytest # is consistent with zuul proxy service_description: name: discoveryServer #service name, corresponding to zuul.routers version: 0.0.2 servicecomb: service: registry: address: http://127.0.0.1:30100 #Service registry address rest: address: 0.0.0.0:8080 The API Gateway access is: [http://127.0.0.1:8754] (http://127.0.0.1:8754), all services defined in zuul.routers can be accessed through this access portal, access The rules are as follows: http://127.0.0.1:8754/myServer/*** This means that Http calls [http://127.0.0.1:8754/myServer/***] (http://127.0.0.1:8754/myServer/***) and will go to the discoveryServer service (for example: \"/myServer/101\" jumps to \"/101\" under the discoveryServer service) If there are multiple discoveryServer services in the service center (version is different), zuul uses the Ribbon policy to forward requests.","title":"Using Zuul Proxy"},{"location":"general-development/AlarmEvent/","text":"Get warning event from Circuit Breaker or Instance Isolation. Senario When the microservice is running, Circuit Breaker or the instance isolation status changes, you need to listen to related events, get relevant information and handle it. Use Reference Monitor CircuitBreaker events Object receiveEvent = new Object() { @Subscribe public void onEvent(CircutBreakerEvent circutBreakerEvent) { //Get information from circutBreakerEvent } }; EventManager.getEventBus().register(receiveEvent); Listen for instance isolation events Object receiveEvent = new Object() { @Subscribe public void onEvent(IsolationServerEvent isolationServerEvent) { //Get information from isolationServerEvent } }; EventManager.getEventBus().register(receiveEvent); Both events are monitored Object receiveEvent = new Object() { @Subscribe public void onEvent(AlarmEvent alarmEvent) { //Get information from alarmEvent } }; EventManager.getEventBus().register(receiveEvent);","title":"Get fuse and instance isolation alarm event information"},{"location":"general-development/AlarmEvent/#get-warning-event-from-circuit-breaker-or-instance-isolation","text":"","title":"Get warning event from Circuit Breaker or Instance Isolation."},{"location":"general-development/AlarmEvent/#senario","text":"When the microservice is running, Circuit Breaker or the instance isolation status changes, you need to listen to related events, get relevant information and handle it.","title":"Senario"},{"location":"general-development/AlarmEvent/#use-reference","text":"Monitor CircuitBreaker events Object receiveEvent = new Object() { @Subscribe public void onEvent(CircutBreakerEvent circutBreakerEvent) { //Get information from circutBreakerEvent } }; EventManager.getEventBus().register(receiveEvent); Listen for instance isolation events Object receiveEvent = new Object() { @Subscribe public void onEvent(IsolationServerEvent isolationServerEvent) { //Get information from isolationServerEvent } }; EventManager.getEventBus().register(receiveEvent); Both events are monitored Object receiveEvent = new Object() { @Subscribe public void onEvent(AlarmEvent alarmEvent) { //Get information from alarmEvent } }; EventManager.getEventBus().register(receiveEvent);","title":"Use Reference"},{"location":"general-development/CORS/","text":"CORS mechanism Concept Description Cross-Origin Resource Sharing (CORS) allows Web servers to perform cross-domain access, enabling browsers to more securely transfer data across domains. Scenario When the user needs to send REST requests across the origin webserver, the CORS mechanism may be used. The microservices that receive cross-domain requests need to enable CORS support. Configuration instructions The CORS function is configured in the microservice.yaml file. The configuration items are described in the following table. | Configuration Item | Default Value | Range of Value | Required | Meaning | | :--- | :--- | :--- | :--- | :--- | :--- | | servicecomb.cors.enabled | false | true / false | No | Whether to enable CORS function | - | | servicecomb.cors.origin | * | - | No | Access-Control-Allow-Origin | - | | servicecomb.cors.allowCredentials | false | true / false | No | Access-Control-Allow-Credentials | According to the CORS standard, when Access-Control-Allow-Credentials is set to true , Access- Control-Allow-Origin cannot be set to \"*\", otherwise an exception will be thrown | | servicecomb.cors.allowedHeader | None | - | No | Access-Control-Allow-Headers | Multiple values \u200b\u200bseparated by commas | | servicecomb.cors.allowedMethod | None | - | No | Access-Control-Allow-Methods | Multiple values \u200b\u200bseparated by commas | | servicecomb.cors.exposedHeader | None | - | No | Access-Control-Expose-Headers | Multiple values \u200b\u200bseparated by commas | | servicecomb.cors.maxAge | None | (0,2147483647], Integer | No | Access-Control-Max-Age | The unit is seconds. If the user does not configure this, there is no Access-Control-Max in the CORS response. Age | Sample Code servicecomb: cors: enabled: true origin: \"*\" allowCredentials: false allowedMethod: PUT,DELETE maxAge: 3600","title":"CORS mechanism"},{"location":"general-development/CORS/#cors-mechanism","text":"","title":"CORS mechanism"},{"location":"general-development/CORS/#concept-description","text":"Cross-Origin Resource Sharing (CORS) allows Web servers to perform cross-domain access, enabling browsers to more securely transfer data across domains.","title":"Concept Description"},{"location":"general-development/CORS/#scenario","text":"When the user needs to send REST requests across the origin webserver, the CORS mechanism may be used. The microservices that receive cross-domain requests need to enable CORS support.","title":"Scenario"},{"location":"general-development/CORS/#configuration-instructions","text":"The CORS function is configured in the microservice.yaml file. The configuration items are described in the following table. | Configuration Item | Default Value | Range of Value | Required | Meaning | | :--- | :--- | :--- | :--- | :--- | :--- | | servicecomb.cors.enabled | false | true / false | No | Whether to enable CORS function | - | | servicecomb.cors.origin | * | - | No | Access-Control-Allow-Origin | - | | servicecomb.cors.allowCredentials | false | true / false | No | Access-Control-Allow-Credentials | According to the CORS standard, when Access-Control-Allow-Credentials is set to true , Access- Control-Allow-Origin cannot be set to \"*\", otherwise an exception will be thrown | | servicecomb.cors.allowedHeader | None | - | No | Access-Control-Allow-Headers | Multiple values \u200b\u200bseparated by commas | | servicecomb.cors.allowedMethod | None | - | No | Access-Control-Allow-Methods | Multiple values \u200b\u200bseparated by commas | | servicecomb.cors.exposedHeader | None | - | No | Access-Control-Expose-Headers | Multiple values \u200b\u200bseparated by commas | | servicecomb.cors.maxAge | None | (0,2147483647], Integer | No | Access-Control-Max-Age | The unit is seconds. If the user does not configure this, there is no Access-Control-Max in the CORS response. Age |","title":"Configuration instructions"},{"location":"general-development/CORS/#sample-code","text":"servicecomb: cors: enabled: true origin: \"*\" allowCredentials: false allowedMethod: PUT,DELETE maxAge: 3600","title":"Sample Code"},{"location":"general-development/QPS/","text":"","title":"QPS"},{"location":"general-development/context/","text":"Delivery Messages through Context ServiceComb provides a Context to delivery data between microservices. Context is a key/value pair and can only use data of type String. Since the Context is serialized into the Json format and passed through the HTTP header, characters other than ASCII are not supported. Other characters require the developer to encode and pass the code. The Context is passed on the request chain in a single request and does not need to be reset. The functions such as trace id of access log are implemented based on this feature. Scenario In the authentication scenario, after the Edge Service authentication is passed, the session ID, username, and other information need to be passed to the microservice to implement authentication and other logic. Grayscale publishing scenarios, need to be combined with custom tags shunt request, tag information needs to be passed to the microservices Use Reference Get and set the Context in Handler The Handler contains the Invocation object, which can be called directly in the invocation.addContext and invocation.getContext settings. Get Context in the service interface Inject through the interface public Response cseResponse(InvocationContext c1) or ContextUtils.getInvocationContext() Set the Context in the Edge Service By override EdgeInvocation EdgeInvocation edgeInvocation = new EdgeInvocation() { protected void createInvocation() { super.createInvocation(); this.invocation.addContext(\"hello\", \"world\"); } };","title":"Using Context to pass control messages"},{"location":"general-development/context/#delivery-messages-through-context","text":"ServiceComb provides a Context to delivery data between microservices. Context is a key/value pair and can only use data of type String. Since the Context is serialized into the Json format and passed through the HTTP header, characters other than ASCII are not supported. Other characters require the developer to encode and pass the code. The Context is passed on the request chain in a single request and does not need to be reset. The functions such as trace id of access log are implemented based on this feature.","title":"Delivery Messages through Context"},{"location":"general-development/context/#scenario","text":"In the authentication scenario, after the Edge Service authentication is passed, the session ID, username, and other information need to be passed to the microservice to implement authentication and other logic. Grayscale publishing scenarios, need to be combined with custom tags shunt request, tag information needs to be passed to the microservices","title":"Scenario"},{"location":"general-development/context/#use-reference","text":"Get and set the Context in Handler The Handler contains the Invocation object, which can be called directly in the invocation.addContext and invocation.getContext settings. Get Context in the service interface Inject through the interface public Response cseResponse(InvocationContext c1) or ContextUtils.getInvocationContext() Set the Context in the Edge Service By override EdgeInvocation EdgeInvocation edgeInvocation = new EdgeInvocation() { protected void createInvocation() { super.createInvocation(); this.invocation.addContext(\"hello\", \"world\"); } };","title":"Use Reference"},{"location":"general-development/cross-app-invocation/","text":"Cross App Invocation Concept Description An application is a layer in the microservice instance isolation hierarchy, and an application contains multiple microservices. By default, only microservice instances of the same application are allowed to call each other. Scenario When a user needs micro-services between different applications to call each other, it is necessary to enable the cross-application calling function. Configuration instructions To enable cross-application calls, you first need to enable cross-application call configuration in the microservice.yaml file on the provider side. Note : * Need to upgrade the micro service version number to re-register micro service information in the service center * Even in the development development environment, you need to upgrade the microservice version number, because in the development environment, only the contract changes, will re-register the contract The configuration items are as follows: service_description: # other configuration omitted properties: allowCrossApp: true # enable cross-app invocation When the consumer client specifies the microservice name to call the provider, it needs to add the application ID to which the provider belongs, and the format becomes [appID]:[microserviceName] . Sample Code The example assumes that the application to which the provider belongs is helloApp, the name of the microservice is helloProvider, the application to which the consumer belongs is helloApp2, and the name of the microservice is helloConsumer. RestTemplate invocation mode When the consumer client develops the microservice consumer in the RestTemplate mode, you need to change [microserviceName] to [appID]:[microserviceName] in the called URL. The code example is as follows: ```java RestTemplate restTemplate = RestTemplateBuilder.create(); ResponseEntity<String> responseEntity = restTemplate .getForEntity(\"cse://helloApp:helloProvider/hello/sayHello?name={name}\", String.class, \"ServiceComb\"); - RPC invocation mode When the consumer client develops a microservice consumer in RPC mode, the declared service provider proxy is as follows: java @RpcReference(schemaId = \"hello\", microserviceName = \"helloApp:helloProvider\") private Hello hello; Cross-application invocation is the same way as invocate microservices under the same application: java hello.sayHello(\"ServiceComb\"); ```","title":"Cross-application invocation"},{"location":"general-development/cross-app-invocation/#cross-app-invocation","text":"","title":"Cross App Invocation"},{"location":"general-development/cross-app-invocation/#concept-description","text":"An application is a layer in the microservice instance isolation hierarchy, and an application contains multiple microservices. By default, only microservice instances of the same application are allowed to call each other.","title":"Concept Description"},{"location":"general-development/cross-app-invocation/#scenario","text":"When a user needs micro-services between different applications to call each other, it is necessary to enable the cross-application calling function.","title":"Scenario"},{"location":"general-development/cross-app-invocation/#configuration-instructions","text":"To enable cross-application calls, you first need to enable cross-application call configuration in the microservice.yaml file on the provider side. Note : * Need to upgrade the micro service version number to re-register micro service information in the service center * Even in the development development environment, you need to upgrade the microservice version number, because in the development environment, only the contract changes, will re-register the contract The configuration items are as follows: service_description: # other configuration omitted properties: allowCrossApp: true # enable cross-app invocation When the consumer client specifies the microservice name to call the provider, it needs to add the application ID to which the provider belongs, and the format becomes [appID]:[microserviceName] .","title":"Configuration instructions"},{"location":"general-development/cross-app-invocation/#sample-code","text":"The example assumes that the application to which the provider belongs is helloApp, the name of the microservice is helloProvider, the application to which the consumer belongs is helloApp2, and the name of the microservice is helloConsumer. RestTemplate invocation mode When the consumer client develops the microservice consumer in the RestTemplate mode, you need to change [microserviceName] to [appID]:[microserviceName] in the called URL. The code example is as follows: ```java RestTemplate restTemplate = RestTemplateBuilder.create(); ResponseEntity<String> responseEntity = restTemplate .getForEntity(\"cse://helloApp:helloProvider/hello/sayHello?name={name}\", String.class, \"ServiceComb\"); - RPC invocation mode When the consumer client develops a microservice consumer in RPC mode, the declared service provider proxy is as follows: java @RpcReference(schemaId = \"hello\", microserviceName = \"helloApp:helloProvider\") private Hello hello; Cross-application invocation is the same way as invocate microservices under the same application: java hello.sayHello(\"ServiceComb\"); ```","title":"Sample Code"},{"location":"general-development/customized-tracing/","text":"Concept Description Distributed call chain tracking provides timing information for calls between services, but the link call information inside the service is equally important to the developer. If you can combine the two into one, you can provide a more complete call chain, which is easier to locate. Errors and potential performance issues. Prerequisites Using the custom dot function requires first configuring and enabling the Java Chassis microservice call chain. Precautions The custom dot function using the @Span annotation only supports method calls that are requesting the same thread as the Java Chassis call. The method to add the @Span annotation must be a Spring-managed bean, otherwise you need to press the [Methods mentioned] (https://stackoverflow.com/questions/41383941/load-time-weaving-for-non-spring -beans-in-a-spring-application) configuration. Custom call chain management This feature integrates Zipkin and provides the @Span annotation for custom tracking of methods that need to be tracked. Java Chassis will automatically track all methods that add @Span annotations, linking the local call information of each method to the call information between services. Steps for usage: Adding dependencies Microservices based on ServiceComb Java Chassis only need to add the following dependency to pom.xml: <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>tracing-zipkin</artifactId> </dependency> Enable custom management function {#Configure tracking processing and data collection} Add the @EnableZipkinTracing annotation to the application portal or Spring configuration class: @SpringBootApplication @EnableZipkinTracing public class ZipkinSpanTestApplication { public static void main(String[] args) { SpringApplication.run(ZipkinSpanTestApplication.class); } } Customized management Add the @Span annotation to the method that requires custom management: @Component public class SlowRepoImpl implements SlowRepo { private static final Logger logger = LoggerFactory.getLogger(SlowRepoImpl.class); private final Random random = new Random(); @Span @Override public String crawl() throws InterruptedException { logger.info(\"in /crawl\"); Thread.sleep(random.nextInt(200)); return \"crawled\"; } } In this way, by using the @Span annotation, we started the Zipkin-based custom management function. Customized reported data The call chain that is escalated by custom management contains two pieces of data: span name defaults to the full name of the method currently being annotated. call.path defaults to the method signature of the current annotation. For example, the data reported in the above example SlowRepoImp is as follows: key value span name crawl call.path public abstract java.lang.String org.apache.servicecomb.tests.tracing.SlowRepo.crawl() throws java.lang.InterruptedException If you need to customize the reported data content, you can pass in the custom parameters: public static class CustomSpanTask { @Span(spanName = \"transaction1\", callPath = \"startA\") public String invoke() { return \"invoke the method\"; } }","title":"Customized-Tracing"},{"location":"general-development/customized-tracing/#concept-description","text":"Distributed call chain tracking provides timing information for calls between services, but the link call information inside the service is equally important to the developer. If you can combine the two into one, you can provide a more complete call chain, which is easier to locate. Errors and potential performance issues.","title":"Concept Description"},{"location":"general-development/customized-tracing/#prerequisites","text":"Using the custom dot function requires first configuring and enabling the Java Chassis microservice call chain.","title":"Prerequisites"},{"location":"general-development/customized-tracing/#precautions","text":"The custom dot function using the @Span annotation only supports method calls that are requesting the same thread as the Java Chassis call. The method to add the @Span annotation must be a Spring-managed bean, otherwise you need to press the [Methods mentioned] (https://stackoverflow.com/questions/41383941/load-time-weaving-for-non-spring -beans-in-a-spring-application) configuration.","title":"Precautions"},{"location":"general-development/customized-tracing/#custom-call-chain-management","text":"This feature integrates Zipkin and provides the @Span annotation for custom tracking of methods that need to be tracked. Java Chassis will automatically track all methods that add @Span annotations, linking the local call information of each method to the call information between services.","title":"Custom call chain management"},{"location":"general-development/customized-tracing/#steps-for-usage","text":"","title":"Steps for usage:"},{"location":"general-development/customized-tracing/#adding-dependencies","text":"Microservices based on ServiceComb Java Chassis only need to add the following dependency to pom.xml: <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>tracing-zipkin</artifactId> </dependency>","title":"Adding dependencies"},{"location":"general-development/customized-tracing/#enable-custom-management-function-configure-tracking-processing-and-data-collection","text":"Add the @EnableZipkinTracing annotation to the application portal or Spring configuration class: @SpringBootApplication @EnableZipkinTracing public class ZipkinSpanTestApplication { public static void main(String[] args) { SpringApplication.run(ZipkinSpanTestApplication.class); } }","title":"Enable custom management function {#Configure tracking processing and data collection}"},{"location":"general-development/customized-tracing/#customized-management","text":"Add the @Span annotation to the method that requires custom management: @Component public class SlowRepoImpl implements SlowRepo { private static final Logger logger = LoggerFactory.getLogger(SlowRepoImpl.class); private final Random random = new Random(); @Span @Override public String crawl() throws InterruptedException { logger.info(\"in /crawl\"); Thread.sleep(random.nextInt(200)); return \"crawled\"; } } In this way, by using the @Span annotation, we started the Zipkin-based custom management function.","title":"Customized management"},{"location":"general-development/customized-tracing/#customized-reported-data","text":"The call chain that is escalated by custom management contains two pieces of data: span name defaults to the full name of the method currently being annotated. call.path defaults to the method signature of the current annotation. For example, the data reported in the above example SlowRepoImp is as follows: key value span name crawl call.path public abstract java.lang.String org.apache.servicecomb.tests.tracing.SlowRepo.crawl() throws java.lang.InterruptedException If you need to customize the reported data content, you can pass in the custom parameters: public static class CustomSpanTask { @Span(spanName = \"transaction1\", callPath = \"startA\") public String invoke() { return \"invoke the method\"; } }","title":"Customized reported data"},{"location":"general-development/dai-li-she-zhi/","text":"background As a developer, in a company development environment, it is possible to access the Internet through a corporate agent network. If debugging services depends on online resources, such as directly connecting to public cloud service center, you must configure the agent. Configuration mode, add proxy configuration in microservice.yaml file: servicecomb: proxy: enable: true #Do you want to enable the proxy? host: yourproxyaddress #proxy address port: 80 #proxy port username: yourname #username passwd: yourpassword #password Configure password using encryption is supported by using SPI. The SPI intrface is org.apache.servicecomb.foundation.common.encrypt.Encryption. Users can implement customer decode interface. Note: Currently only supports connection service center, configuration center support agent. If you connect other three-party services, you can read this configuration, configure the agent yourself, vertx httpclient supports proxy settings, for example: HttpClientOptions httpClientOptions = new HttpClientOptions(); If (isProxyEnable()) { ProxyOptions proxy = new ProxyOptions(); proxy.setHost(\"host\"); proxy.setPort(port); proxy.setUsername(\"username\"); proxy.setPassword(\"passwd\"); httpClientOptions.setProxyOptions(proxy); }","title":"Proxy Settings"},{"location":"general-development/dai-li-she-zhi/#background","text":"As a developer, in a company development environment, it is possible to access the Internet through a corporate agent network. If debugging services depends on online resources, such as directly connecting to public cloud service center, you must configure the agent. Configuration mode, add proxy configuration in microservice.yaml file: servicecomb: proxy: enable: true #Do you want to enable the proxy? host: yourproxyaddress #proxy address port: 80 #proxy port username: yourname #username passwd: yourpassword #password Configure password using encryption is supported by using SPI. The SPI intrface is org.apache.servicecomb.foundation.common.encrypt.Encryption. Users can implement customer decode interface. Note: Currently only supports connection service center, configuration center support agent. If you connect other three-party services, you can read this configuration, configure the agent yourself, vertx httpclient supports proxy settings, for example: HttpClientOptions httpClientOptions = new HttpClientOptions(); If (isProxyEnable()) { ProxyOptions proxy = new ProxyOptions(); proxy.setHost(\"host\"); proxy.setPort(port); proxy.setUsername(\"username\"); proxy.setPassword(\"passwd\"); httpClientOptions.setProxyOptions(proxy); }","title":"background"},{"location":"general-development/ding-zhi-xu-lie-hua-he-fan-xu-lie-hua-fang-fa/","text":"","title":"Ding zhi xu lie hua he fan xu lie hua fang fa"},{"location":"general-development/dnsconfig/","text":"Scenario When a user uses a domain name to connect to a public cloud or a third-party system, you need to use the domain name resolution DNS system. The DNS used in different systems and different frameworks may be different. Therefore, it is necessary to provide a unified configuration entry so that development and operation personnel can customize the DNS resolution mechanism without being completely subject to system configuration. DNS Configuration The DNS configuration item is written in the microservice.yaml file. It supports the unified development of certificates. It can also add tags for more fine-grained configuration. The tag configuration overrides the global configuration. The configuration format is as follows: addressResolver.[tag].[property] The common tags are as follows: Project tag Service Center sc.consumer Configuration Center cc.consumer User Defined self.tag The detailed description of each property (Set Vertx DNS resolution) addressResolver: servers: 8.8.8.8, 8.8.4.4 #corresponds to the nameserver of Linux /etc/resolv.conf, the DNS server address, supports multiple configurations, separated by commas ndots: 1 # corresponds to the options in linux /etc/resolv.conf: ndots, the role is that if the number of points contained in the domain name is less than the threshold, then DNS resolution will be added by default to the value of searchDomains. This must be used in conjunction with searchDomains. searchDomains: a, b, c # Corresponding to the search in linux /etc/resolv.conf, and ndots, if the number of points in the current domain name is less than the set value, these values will be added to the domain name and parsed together when parsing, for example, the ndots is set to 4. The current domain name is servicecomb.cn-north-1.myhwclouds.com, only three points. Then the servicecomb.cn-north-1.myhwclouds.com.a will be automatically parsed when parsing, not parsed out. Servicecomb.cn-north-1.myhwclouds.com.b until it can be finally parsed optResourceEnabled: true #optional record is automatically included in DNS queries cacheMinTimeToLive: 0 #minimum cache time cacheMaxTimeToLive: 10000 #Maximum cache time cacheNegativeTimeToLive: 0 #DNS resolving failure time after the next retry queryTimeout: 5000 #Query timeout maxQueries: 4 #Query times rdFlag: true #Set DNS recursive query rotateServers: true #Set whether to support polling example VertxOptions vertxOptions = new VertxOptions(); vertxOptions.setAddressResolverOptions(AddressResolverConfig.getAddressResover(\"self.tag\")); Vertx vertx = VertxUtils.getOrCreateVertxByName(\"registry\", vertxOptions); // this has to set the client options HttpClientOptions httpClientOptions = createHttpClientOptions(); ClientPoolManager<HttpClientWithContext> clientMgr = new ClientPoolManager<>(vertx, new HttpClientPoolFactory(httpClientOptions)); clientMgr.findThreadBindClientPool().runOnContext(httpClient -> { // do some http request });","title":"DNS Custom Configuration"},{"location":"general-development/dnsconfig/#scenario","text":"When a user uses a domain name to connect to a public cloud or a third-party system, you need to use the domain name resolution DNS system. The DNS used in different systems and different frameworks may be different. Therefore, it is necessary to provide a unified configuration entry so that development and operation personnel can customize the DNS resolution mechanism without being completely subject to system configuration.","title":"Scenario"},{"location":"general-development/dnsconfig/#dns-configuration","text":"The DNS configuration item is written in the microservice.yaml file. It supports the unified development of certificates. It can also add tags for more fine-grained configuration. The tag configuration overrides the global configuration. The configuration format is as follows: addressResolver.[tag].[property] The common tags are as follows: Project tag Service Center sc.consumer Configuration Center cc.consumer User Defined self.tag The detailed description of each property (Set Vertx DNS resolution) addressResolver: servers: 8.8.8.8, 8.8.4.4 #corresponds to the nameserver of Linux /etc/resolv.conf, the DNS server address, supports multiple configurations, separated by commas ndots: 1 # corresponds to the options in linux /etc/resolv.conf: ndots, the role is that if the number of points contained in the domain name is less than the threshold, then DNS resolution will be added by default to the value of searchDomains. This must be used in conjunction with searchDomains. searchDomains: a, b, c # Corresponding to the search in linux /etc/resolv.conf, and ndots, if the number of points in the current domain name is less than the set value, these values will be added to the domain name and parsed together when parsing, for example, the ndots is set to 4. The current domain name is servicecomb.cn-north-1.myhwclouds.com, only three points. Then the servicecomb.cn-north-1.myhwclouds.com.a will be automatically parsed when parsing, not parsed out. Servicecomb.cn-north-1.myhwclouds.com.b until it can be finally parsed optResourceEnabled: true #optional record is automatically included in DNS queries cacheMinTimeToLive: 0 #minimum cache time cacheMaxTimeToLive: 10000 #Maximum cache time cacheNegativeTimeToLive: 0 #DNS resolving failure time after the next retry queryTimeout: 5000 #Query timeout maxQueries: 4 #Query times rdFlag: true #Set DNS recursive query rotateServers: true #Set whether to support polling","title":"DNS Configuration"},{"location":"general-development/dnsconfig/#example","text":"VertxOptions vertxOptions = new VertxOptions(); vertxOptions.setAddressResolverOptions(AddressResolverConfig.getAddressResover(\"self.tag\")); Vertx vertx = VertxUtils.getOrCreateVertxByName(\"registry\", vertxOptions); // this has to set the client options HttpClientOptions httpClientOptions = createHttpClientOptions(); ClientPoolManager<HttpClientWithContext> clientMgr = new ClientPoolManager<>(vertx, new HttpClientPoolFactory(httpClientOptions)); clientMgr.findThreadBindClientPool().runOnContext(httpClient -> { // do some http request });","title":"example"},{"location":"general-development/error-handling/","text":"Handle exceptions ServiceComb has three categories of exceptions\uff1a * User Defined Exceptions\uff1aExceptions defined in API. These exceptions are generated to swagger. Control Messages Exceptions\uff1aMost of them are thrown by handlers. e.g. Flow control throws TOO_MANY_REQUESTS_STATUS. java CommonExceptionData errorData = new CommonExceptionData(\"rejected by qps flowcontrol\"); asyncResp.producerFail(new InvocationException(QpsConst.TOO_MANY_REQUESTS_STATUS, errorData)); Unknown Exceptions\uff1aUnkown exceptions may throw by service implementation like NullPointerException or network SocketException. These exceptions will be caught by ServiceComb and return 490, 590 like error code. e.g. java CommonExceptionData errorData = new CommonExceptionData(cause.getMessage()); asyncResp.producerFail(new InvocationException(590, errorData) or java asyncResp.consumerFail(new InvocationException(490, errorData) User Defined Exceptions Users can use @ApiResonse to define different types of exceptions. e.g. @Path(\"/errorCode\") @POST @ApiResponses({ @ApiResponse(code = 200, response = MultiResponse200.class, message = \"\"), @ApiResponse(code = 400, response = MultiResponse400.class, message = \"\"), @ApiResponse(code = 500, response = MultiResponse500.class, message = \"\")}) public MultiResponse200 errorCode(MultiRequest request) { if (request.getCode() == 400) { MultiResponse400 r = new MultiResponse400(); r.setCode(400); r.setMessage(\"bad request\"); throw new InvocationException(javax.ws.rs.core.Response.Status.BAD_REQUEST, r); } else if (request.getCode() == 500) { MultiResponse500 r = new MultiResponse500(); r.setCode(500); r.setMessage(\"internal error\"); throw new InvocationException(javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR, r); } else { MultiResponse200 r = new MultiResponse200(); r.setCode(200); r.setMessage(\"success result\"); return r; } } and client code know exception type. MultiRequest request = new MultiRequest(); request.setCode(200); ResponseEntity<MultiResponse200> result = template .postForEntity(SERVER + \"/MultiErrorCodeService/errorCode\", request, MultiResponse200.class); TestMgr.check(result.getStatusCode(), 200); TestMgr.check(result.getBody().getMessage(), \"success result\"); request.setCode(400); MultiResponse400 t400 = null; try { template.postForEntity(SERVER + \"/MultiErrorCodeService/errorCode\", request, MultiResponse400.class); } catch (InvocationException e) { t400 = (MultiResponse400) e.getErrorData(); } TestMgr.check(t400.getCode(), 400); TestMgr.check(t400.getMessage(), \"bad request\"); request.setCode(500); MultiResponse500 t500 = null; try { template.postForEntity(SERVER + \"/MultiErrorCodeService/errorCode\", request, MultiResponse400.class); } catch (InvocationException e) { t500 = (MultiResponse500) e.getErrorData(); } TestMgr.check(t500.getCode(), 500); TestMgr.check(t500.getMessage(), \"internal error\"); Control Messages Exceptions Control message exceptions not defined in swagger and the type is unknown for serializers. Client code use raw type to process it. JsonObject requestJson = new JsonObject(); requestJson.put(\"code\", 400); requestJson.put(\"message\", \"test message\"); try { template .postForEntity(SERVER + \"/MultiErrorCodeService/noClientErrorCode\", requestJson, Object.class); } catch (InvocationException e) { TestMgr.check(e.getStatusCode(), 400); mapResult = RestObjectMapperFactory.getRestObjectMapper().convertValue(e.getErrorData(), Map.class); TestMgr.check(mapResult.get(\"message\"), \"test message\"); TestMgr.check(mapResult.get(\"code\"), 400); TestMgr.check(mapResult.get(\"t400\"), 400); } The above code assume the type of exception data is unknown and convert it to map. Usually, ServiceComb throws its control messages exception with CommonExceptionData. Unknown Exceptions Unknown exceptions are wrapped to 490 and 590 error code, and type is CommonExceptionData. Customize exceptions type We can define actual types for error code and convert one type of exception to another. define actual types for error code Define actual types for error code can make consumer code easier, and do not to use raw types. Users can implement a SPI interface org.apache.servicecomb.swagger.invocation.response.ResponseMetaMapper to specify the target exception type for specific error code. ```java private final static Map CODES = new HashMap<>(1); static { ResponseMeta meta = new ResponseMeta(); meta.setJavaType(SimpleType.constructUnsafe(IllegalStateErrorData.class)); CODES.put(500, meta); } @Override public Map<Integer, ResponseMeta> getMapper() { return CODES; } ``` convert one type of exception to another ServiceComb will serialize InvocationException data to response, and when the exception type is not InvocationException , a wrapped InvocationException with error code 490, 590 is created. Implement SPI interface org.apache.servicecomb.swagger.invocation.exception.ExceptionToProducerResponseConverter can convert one type of exception to another. Here is the description about ExceptionToProducerResponseConverter : - the method getExceptionClass() indicates which type of exception this converter handles. The converter whose getExceptionClass() method returns null will be taken as default converter. - in the method Response convert(SwaggerInvocation swaggerInvocation, T e) , the exception is processed and Response is returned. The returned Response determines the status code, resposne body of the HTTP response. - the method getOrder() determines the priority of a converter. The less the returned value is, the higher the priority is. If the converter does not implement this method, the default return value is 0 . For a certain type of exception, only the converter with the highest priority will take effect. - When an exception comes, the converters will be selected according to its type. If no converter is selected, then the type of its parent class is used to select the converter. Such process will continue until the Throwable type is used to select converter. If there is still no converter for this exception, the default converter will be selected to process this type of exception. ```java public class CustomExceptionToProducerResponseConverter implements ExceptionToProducerResponseConverter { @Override public Class getExceptionClass() { // The return value indicates that this converter handles IllegalStateException return IllegalStateException.class; } @Override public int getOrder() { // The less the returned value is, the higher the priority is return 100; } @Override public Response convert(SwaggerInvocation swaggerInvocation, IllegalStateException e) { // Here the exception is processed IllegalStateErrorData data = new IllegalStateErrorData(); data.setId(500); data.setMessage(e.getMessage()); data.setState(e.getMessage()); InvocationException state = new InvocationException(Status.INTERNAL_SERVER_ERROR, data); return Response.failResp(state); } } ```","title":"Handling exceptions"},{"location":"general-development/error-handling/#handle-exceptions","text":"ServiceComb has three categories of exceptions\uff1a * User Defined Exceptions\uff1aExceptions defined in API. These exceptions are generated to swagger. Control Messages Exceptions\uff1aMost of them are thrown by handlers. e.g. Flow control throws TOO_MANY_REQUESTS_STATUS. java CommonExceptionData errorData = new CommonExceptionData(\"rejected by qps flowcontrol\"); asyncResp.producerFail(new InvocationException(QpsConst.TOO_MANY_REQUESTS_STATUS, errorData)); Unknown Exceptions\uff1aUnkown exceptions may throw by service implementation like NullPointerException or network SocketException. These exceptions will be caught by ServiceComb and return 490, 590 like error code. e.g. java CommonExceptionData errorData = new CommonExceptionData(cause.getMessage()); asyncResp.producerFail(new InvocationException(590, errorData) or java asyncResp.consumerFail(new InvocationException(490, errorData)","title":"Handle exceptions"},{"location":"general-development/error-handling/#user-defined-exceptions","text":"Users can use @ApiResonse to define different types of exceptions. e.g. @Path(\"/errorCode\") @POST @ApiResponses({ @ApiResponse(code = 200, response = MultiResponse200.class, message = \"\"), @ApiResponse(code = 400, response = MultiResponse400.class, message = \"\"), @ApiResponse(code = 500, response = MultiResponse500.class, message = \"\")}) public MultiResponse200 errorCode(MultiRequest request) { if (request.getCode() == 400) { MultiResponse400 r = new MultiResponse400(); r.setCode(400); r.setMessage(\"bad request\"); throw new InvocationException(javax.ws.rs.core.Response.Status.BAD_REQUEST, r); } else if (request.getCode() == 500) { MultiResponse500 r = new MultiResponse500(); r.setCode(500); r.setMessage(\"internal error\"); throw new InvocationException(javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR, r); } else { MultiResponse200 r = new MultiResponse200(); r.setCode(200); r.setMessage(\"success result\"); return r; } } and client code know exception type. MultiRequest request = new MultiRequest(); request.setCode(200); ResponseEntity<MultiResponse200> result = template .postForEntity(SERVER + \"/MultiErrorCodeService/errorCode\", request, MultiResponse200.class); TestMgr.check(result.getStatusCode(), 200); TestMgr.check(result.getBody().getMessage(), \"success result\"); request.setCode(400); MultiResponse400 t400 = null; try { template.postForEntity(SERVER + \"/MultiErrorCodeService/errorCode\", request, MultiResponse400.class); } catch (InvocationException e) { t400 = (MultiResponse400) e.getErrorData(); } TestMgr.check(t400.getCode(), 400); TestMgr.check(t400.getMessage(), \"bad request\"); request.setCode(500); MultiResponse500 t500 = null; try { template.postForEntity(SERVER + \"/MultiErrorCodeService/errorCode\", request, MultiResponse400.class); } catch (InvocationException e) { t500 = (MultiResponse500) e.getErrorData(); } TestMgr.check(t500.getCode(), 500); TestMgr.check(t500.getMessage(), \"internal error\");","title":"User Defined Exceptions"},{"location":"general-development/error-handling/#control-messages-exceptions","text":"Control message exceptions not defined in swagger and the type is unknown for serializers. Client code use raw type to process it. JsonObject requestJson = new JsonObject(); requestJson.put(\"code\", 400); requestJson.put(\"message\", \"test message\"); try { template .postForEntity(SERVER + \"/MultiErrorCodeService/noClientErrorCode\", requestJson, Object.class); } catch (InvocationException e) { TestMgr.check(e.getStatusCode(), 400); mapResult = RestObjectMapperFactory.getRestObjectMapper().convertValue(e.getErrorData(), Map.class); TestMgr.check(mapResult.get(\"message\"), \"test message\"); TestMgr.check(mapResult.get(\"code\"), 400); TestMgr.check(mapResult.get(\"t400\"), 400); } The above code assume the type of exception data is unknown and convert it to map. Usually, ServiceComb throws its control messages exception with CommonExceptionData.","title":"Control Messages Exceptions"},{"location":"general-development/error-handling/#unknown-exceptions","text":"Unknown exceptions are wrapped to 490 and 590 error code, and type is CommonExceptionData.","title":"Unknown Exceptions"},{"location":"general-development/error-handling/#customize-exceptions-type","text":"We can define actual types for error code and convert one type of exception to another. define actual types for error code Define actual types for error code can make consumer code easier, and do not to use raw types. Users can implement a SPI interface org.apache.servicecomb.swagger.invocation.response.ResponseMetaMapper to specify the target exception type for specific error code. ```java private final static Map CODES = new HashMap<>(1); static { ResponseMeta meta = new ResponseMeta(); meta.setJavaType(SimpleType.constructUnsafe(IllegalStateErrorData.class)); CODES.put(500, meta); } @Override public Map<Integer, ResponseMeta> getMapper() { return CODES; } ``` convert one type of exception to another ServiceComb will serialize InvocationException data to response, and when the exception type is not InvocationException , a wrapped InvocationException with error code 490, 590 is created. Implement SPI interface org.apache.servicecomb.swagger.invocation.exception.ExceptionToProducerResponseConverter can convert one type of exception to another. Here is the description about ExceptionToProducerResponseConverter : - the method getExceptionClass() indicates which type of exception this converter handles. The converter whose getExceptionClass() method returns null will be taken as default converter. - in the method Response convert(SwaggerInvocation swaggerInvocation, T e) , the exception is processed and Response is returned. The returned Response determines the status code, resposne body of the HTTP response. - the method getOrder() determines the priority of a converter. The less the returned value is, the higher the priority is. If the converter does not implement this method, the default return value is 0 . For a certain type of exception, only the converter with the highest priority will take effect. - When an exception comes, the converters will be selected according to its type. If no converter is selected, then the type of its parent class is used to select the converter. Such process will continue until the Throwable type is used to select converter. If there is still no converter for this exception, the default converter will be selected to process this type of exception. ```java public class CustomExceptionToProducerResponseConverter implements ExceptionToProducerResponseConverter { @Override public Class getExceptionClass() { // The return value indicates that this converter handles IllegalStateException return IllegalStateException.class; } @Override public int getOrder() { // The less the returned value is, the higher the priority is return 100; } @Override public Response convert(SwaggerInvocation swaggerInvocation, IllegalStateException e) { // Here the exception is processed IllegalStateErrorData data = new IllegalStateErrorData(); data.setId(500); data.setMessage(e.getMessage()); data.setState(e.getMessage()); InvocationException state = new InvocationException(Status.INTERNAL_SERVER_ERROR, data); return Response.failResp(state); } } ```","title":"Customize exceptions type"},{"location":"general-development/file-download/","text":"File downloads are currently available in the vertx rest channel and servlet rest. First, producer 1. Download normal files return new File(......); 2. Download temporary files In this scenario, you need to create temporary files based on the request parameters dynamically. After the download is complete, you need to delete the temporary files. return new FilePart(file).setDeleteAfterFinished(true); 3. Download org.springframework.core.io.Resource Because the resource does not necessarily mean file download, you need to identify this file download scenario by swagger annotation (@ApiResponse). Take ByteArrayResource as an example: @GetMapping(path = \"/resource\") @ApiResponses({ @ApiResponse(code = 200, response = File.class, message = \"\") }) public Resource resource() { ...... return new ByteArrayResource(bytes) { @Override public String getFilename() { return \"resource.txt\"; } }; } In the above example, because ByteArrayResource does not have the concept of a file name, you need to implement the resource's getFilename method, or you can wrap it with ResponseEntity: @GetMapping(path = \"/resource\") @ApiResponses({ @ApiResponse(code = 200, response = File.class, message = \"\") }) public ResponseEntity<Resource> resource() { ...... return ResponseEntity .ok() .header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE) .header(HttpHeaders.CONTENT_DISPOSITION, \"attachment;filename=resource.txt\") .body(resource); } 4.Download InputStream Because InputStream does not mean file downloading for sure, it needs to be annotated by 'swagger annotation' (@ApiResponse). This is a file download scenario. In some scenarios, resources are not stored locally. return ResponseEntity .ok() .header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE) .header(HttpHeaders.CONTENT_DISPOSITION, \"attachment;filename=resource.txt\") .body(stream); After the download is complete, ServiceComb will automatically close the stream, and developers don't have to pay attention 5. File type determination As long as the HttpHeaders.CONTENT_TYPE is not set directly via ResponseEntity, ServiceComb will try to automatically determine the file name suffix in File, Part, and Resource. ServiceComb uses java's mime type mechanism for file type determination. If the file suffix in the business scenario cannot be identified, ServiceComb will default to application/octet-stream. If this does not meet the requirements, assuming the file suffix is, and the expected file type is application/file-xyz, any of the following methods can be resolved: 1) Extend via Java's mime type mechanism In the META-INF directory, create a mime. Types file with the contents: application/file-xyz xyz 2) Specify by Part in the business code return new FilePart(null, file).contentType(\"application/file-xyz\"); 3) specified in the business code by ResponseEntity return ResponseEntity .ok() .header(HttpHeaders.CONTENT_TYPE, \"application/file-xyz\") .body(\u2026\u2026); .body(...); 6.File name As long as HttpHeaders.CONTENT_DISPOSITION is not set directly via ResponseEntity, ServiceComb will try to generate HttpHeaders.CONTENT_DISPOSITION through the file names in File, Part, and Resource. Assuming the file name is file.txt, the generated data is as follows: Content-Disposition: attachment;filename=file.txt;filename*=utf-8\u2019\u2019file.txt Not only the filename is generated, but also filename* is generated. This is because if there is Chinese, space, and filename correctly in the file name, i.e., chrome is fine, but firefox directly treats the string after the encoding as a text. The name of the item is used directly. Firefox only decodes filename* according to [https://tools.ietf.org/html/rtf6266] (https://tools.ietf.org/html/rtf6266). If Content-Disposition is set directly in the business code, you need to handle the problems supported by multiple browsers. Second, Consumer The consumer side uses org.apache.servicecomb.foundation.vertx.http.ReadStreamPart to process file downloads. 1. Transparent RPC public interface ......{ ReadStreamPart download1(...); ReadStreamPart download2(...); } 2.RestTemplate Take get as an example: ReadStreamPart part = restTemplate.getForObject(url, ReadStreamPart.class); 3. Read data from ReadStreamPart ReadStreamPart provides a set of methods to save the data stream as local data: org.apache.servicecomb.foundation.vertx.http.ReadStreamPart.saveAsBytes() org.apache.servicecomb.foundation.vertx.http.ReadStreamPart.saveAsString() org.apache.servicecomb.foundation.vertx.http.ReadStreamPart.saveToFile(String) org.apache.servicecomb.foundation.vertx.http.ReadStreamPart.saveToFile(File, OpenOptions) note: When the ReadStreamPart instance is obtained, the file content is not downloaded. The save or other methods is called to start reading the file data from the network. If you use saveAsBytes, saveAsString, the data is directly stored in the memory; if the downloaded file is large, there will be a risk of memory explosion. The save series method returns all CompletableFuture objects: * If you want to block waiting for the download to complete, you can use future.get() * If asynchronous callback processing is performed through future.whenComplete, be aware that callbacks occur in network threads, and you must follow the reactive thread rules.","title":"File Downloading"},{"location":"general-development/file-download/#first-producer","text":"","title":"First, producer"},{"location":"general-development/file-download/#1-download-normal-files","text":"return new File(......);","title":"1. Download normal files"},{"location":"general-development/file-download/#2-download-temporary-files","text":"In this scenario, you need to create temporary files based on the request parameters dynamically. After the download is complete, you need to delete the temporary files. return new FilePart(file).setDeleteAfterFinished(true);","title":"2. Download temporary files"},{"location":"general-development/file-download/#3-download-orgspringframeworkcoreioresource","text":"Because the resource does not necessarily mean file download, you need to identify this file download scenario by swagger annotation (@ApiResponse). Take ByteArrayResource as an example: @GetMapping(path = \"/resource\") @ApiResponses({ @ApiResponse(code = 200, response = File.class, message = \"\") }) public Resource resource() { ...... return new ByteArrayResource(bytes) { @Override public String getFilename() { return \"resource.txt\"; } }; } In the above example, because ByteArrayResource does not have the concept of a file name, you need to implement the resource's getFilename method, or you can wrap it with ResponseEntity: @GetMapping(path = \"/resource\") @ApiResponses({ @ApiResponse(code = 200, response = File.class, message = \"\") }) public ResponseEntity<Resource> resource() { ...... return ResponseEntity .ok() .header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE) .header(HttpHeaders.CONTENT_DISPOSITION, \"attachment;filename=resource.txt\") .body(resource); }","title":"3. Download org.springframework.core.io.Resource"},{"location":"general-development/file-download/#4download-inputstream","text":"Because InputStream does not mean file downloading for sure, it needs to be annotated by 'swagger annotation' (@ApiResponse). This is a file download scenario. In some scenarios, resources are not stored locally. return ResponseEntity .ok() .header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE) .header(HttpHeaders.CONTENT_DISPOSITION, \"attachment;filename=resource.txt\") .body(stream); After the download is complete, ServiceComb will automatically close the stream, and developers don't have to pay attention","title":"4.Download InputStream"},{"location":"general-development/file-download/#5-file-type-determination","text":"As long as the HttpHeaders.CONTENT_TYPE is not set directly via ResponseEntity, ServiceComb will try to automatically determine the file name suffix in File, Part, and Resource. ServiceComb uses java's mime type mechanism for file type determination. If the file suffix in the business scenario cannot be identified, ServiceComb will default to application/octet-stream. If this does not meet the requirements, assuming the file suffix is, and the expected file type is application/file-xyz, any of the following methods can be resolved:","title":"5. File type determination"},{"location":"general-development/file-download/#1-extend-via-javas-mime-type-mechanism","text":"In the META-INF directory, create a mime. Types file with the contents: application/file-xyz xyz","title":"1) Extend via Java's mime type mechanism"},{"location":"general-development/file-download/#2-specify-by-part-in-the-business-code","text":"return new FilePart(null, file).contentType(\"application/file-xyz\");","title":"2) Specify by Part in the business code"},{"location":"general-development/file-download/#3-specified-in-the-business-code-by-responseentity","text":"return ResponseEntity .ok() .header(HttpHeaders.CONTENT_TYPE, \"application/file-xyz\") .body(\u2026\u2026); .body(...);","title":"3) specified in the business code by ResponseEntity"},{"location":"general-development/file-download/#6file-name","text":"As long as HttpHeaders.CONTENT_DISPOSITION is not set directly via ResponseEntity, ServiceComb will try to generate HttpHeaders.CONTENT_DISPOSITION through the file names in File, Part, and Resource. Assuming the file name is file.txt, the generated data is as follows: Content-Disposition: attachment;filename=file.txt;filename*=utf-8\u2019\u2019file.txt Not only the filename is generated, but also filename* is generated. This is because if there is Chinese, space, and filename correctly in the file name, i.e., chrome is fine, but firefox directly treats the string after the encoding as a text. The name of the item is used directly. Firefox only decodes filename* according to [https://tools.ietf.org/html/rtf6266] (https://tools.ietf.org/html/rtf6266). If Content-Disposition is set directly in the business code, you need to handle the problems supported by multiple browsers.","title":"6.File name"},{"location":"general-development/file-download/#second-consumer","text":"The consumer side uses org.apache.servicecomb.foundation.vertx.http.ReadStreamPart to process file downloads.","title":"Second, Consumer"},{"location":"general-development/file-download/#1-transparent-rpc","text":"public interface ......{ ReadStreamPart download1(...); ReadStreamPart download2(...); }","title":"1. Transparent RPC"},{"location":"general-development/file-download/#2resttemplate","text":"Take get as an example: ReadStreamPart part = restTemplate.getForObject(url, ReadStreamPart.class);","title":"2.RestTemplate"},{"location":"general-development/file-download/#3-read-data-from-readstreampart","text":"ReadStreamPart provides a set of methods to save the data stream as local data: org.apache.servicecomb.foundation.vertx.http.ReadStreamPart.saveAsBytes() org.apache.servicecomb.foundation.vertx.http.ReadStreamPart.saveAsString() org.apache.servicecomb.foundation.vertx.http.ReadStreamPart.saveToFile(String) org.apache.servicecomb.foundation.vertx.http.ReadStreamPart.saveToFile(File, OpenOptions) note: When the ReadStreamPart instance is obtained, the file content is not downloaded. The save or other methods is called to start reading the file data from the network. If you use saveAsBytes, saveAsString, the data is directly stored in the memory; if the downloaded file is large, there will be a risk of memory explosion. The save series method returns all CompletableFuture objects: * If you want to block waiting for the download to complete, you can use future.get() * If asynchronous callback processing is performed through future.whenComplete, be aware that callbacks occur in network threads, and you must follow the reactive thread rules.","title":"3. Read data from ReadStreamPart"},{"location":"general-development/file-upload/","text":"File upload, currently supported in vertx rest channel and servlet rest. File uploads use the standard http form format, which can directly upload the file from the browser. Producer: Support jaxrs and springmvc development mode Jaxrs development model: * javax.servlet.http.Part type that supports servlet definitions You can directly use @FormParam to pass file types and common parameters Springmvc development mode: Supports servlet-defined javax.servlet.http.Part type, also supports org.springframework.web.multipart.MultipartFile type The two datatype functions are consistent, and MultipartFile is also base on Part type Two data types can be mixed, for example, the first parameter is Part and the second parameter is MultipartFile You can directly use @RequestPart to pass file types and common parameters note: First file upload temporary directory, the default is null does not support file upload, file upload request Content-Type must be multipart/form-data The same name parameter only supports one file Supports transferring files with multiple different parameter names at one time After opening the stream through MultipartFile or Part, remember to close it. Otherwise the uploaded temporary file will not be deleted, and eventually, the upload temporary directory will be exploded. Sample code in Springmvc mode: @PostMapping(path = \"/upload\", consumes = MediaType.MULTIPART_FORM_DATA) public String fileUpload(@RequestPart(name = \"file1\") MultipartFile file1, @RequestPart(name = \"file2\") Part file2, @RequestPart String param1) { ...... } Configuration instructions: | Configuration Item | Default Value | Range of Value | | :--- | :--- | :--- | :--- | | servicecomb.uploads.directory | null | | In which directory the uploaded temporary file is saved, default value null means file upload is not supported | | servicecomb.uploads.maxSize | -1 | | The maximum allowable size of http body in bytes. the default value of -1 means unlimited | Consumer: The following data types are supported: java.io.File javax.servlet.http.Part java.io.InputStream org.springframework.core.io.Resource When using InputStream, because it is a stream, there is no concept of client file name at this time, so the producer will get the client file name will get null. If you want to use both memory data and the producer to get the client file name, you can use the resource type, inherit org.springframework.core.io.ByteArrayResource, and override getFilename. Transparent RPC Code Sample: interface UploadIntf { String upload(File file); } After getting the interface reference, you can call it directly: String result = uploadIntf.upload(file); RestTemplate code example: Map<String, Object> map = new HashMap<>(); map.put(\"file\", new FileSystemResource(\"a file path!\")); map.put(\"param1\", \"test\"); HttpHeaders headers = new HttpHeaders(); headers.setContentType(org.springframework.http.MediaType.MULTIPART_FORM_DATA); HttpEntity<Map<String, Object>> entry = new HttpEntity<>(map, headers); String reseult = template.postForObject( url, entry, String.class);","title":"File Uploading"},{"location":"general-development/file-upload/#producer","text":"Support jaxrs and springmvc development mode Jaxrs development model: * javax.servlet.http.Part type that supports servlet definitions You can directly use @FormParam to pass file types and common parameters Springmvc development mode: Supports servlet-defined javax.servlet.http.Part type, also supports org.springframework.web.multipart.MultipartFile type The two datatype functions are consistent, and MultipartFile is also base on Part type Two data types can be mixed, for example, the first parameter is Part and the second parameter is MultipartFile You can directly use @RequestPart to pass file types and common parameters note: First file upload temporary directory, the default is null does not support file upload, file upload request Content-Type must be multipart/form-data The same name parameter only supports one file Supports transferring files with multiple different parameter names at one time After opening the stream through MultipartFile or Part, remember to close it. Otherwise the uploaded temporary file will not be deleted, and eventually, the upload temporary directory will be exploded. Sample code in Springmvc mode: @PostMapping(path = \"/upload\", consumes = MediaType.MULTIPART_FORM_DATA) public String fileUpload(@RequestPart(name = \"file1\") MultipartFile file1, @RequestPart(name = \"file2\") Part file2, @RequestPart String param1) { ...... }","title":"Producer:"},{"location":"general-development/file-upload/#configuration-instructions","text":"| Configuration Item | Default Value | Range of Value | | :--- | :--- | :--- | :--- | | servicecomb.uploads.directory | null | | In which directory the uploaded temporary file is saved, default value null means file upload is not supported | | servicecomb.uploads.maxSize | -1 | | The maximum allowable size of http body in bytes. the default value of -1 means unlimited |","title":"Configuration instructions:"},{"location":"general-development/file-upload/#consumer","text":"The following data types are supported: java.io.File javax.servlet.http.Part java.io.InputStream org.springframework.core.io.Resource When using InputStream, because it is a stream, there is no concept of client file name at this time, so the producer will get the client file name will get null. If you want to use both memory data and the producer to get the client file name, you can use the resource type, inherit org.springframework.core.io.ByteArrayResource, and override getFilename.","title":"Consumer:"},{"location":"general-development/file-upload/#transparent-rpc-code-sample","text":"interface UploadIntf { String upload(File file); } After getting the interface reference, you can call it directly: String result = uploadIntf.upload(file);","title":"Transparent RPC Code Sample:"},{"location":"general-development/file-upload/#resttemplate-code-example","text":"Map<String, Object> map = new HashMap<>(); map.put(\"file\", new FileSystemResource(\"a file path!\")); map.put(\"param1\", \"test\"); HttpHeaders headers = new HttpHeaders(); headers.setContentType(org.springframework.http.MediaType.MULTIPART_FORM_DATA); HttpEntity<Map<String, Object>> entry = new HttpEntity<>(map, headers); String reseult = template.postForObject( url, entry, String.class);","title":"RestTemplate code example:"},{"location":"general-development/gated-launch/","text":"","title":"Gated launch"},{"location":"general-development/http-filter/","text":"In some scenarios, the service uses http instead of https as the network transmission channel. To prevent the falsification or tampering request, consumer and the producer must be provided a method to signature the http stream. The signature method is carried using the org.apache.servicecomb.common.rest.filter.HttpClientFilter and org.apache.servicecomb.common.rest.filter.HttpServerFilter interfaces. It is recommended that the http stream related logic use the Filter mechanism here, and the contract The parameter related logic uses the Handler mechanism. About the use of the Filter interface, please reference [demo-signature] (https://github.com/ServiceComb/ServiceComb-Java-Chassis/tree/master/demo/demo-signature). 1 Overview The Filter mechanism is loaded using the Java standard SPI mechanism. Both HttpClientFilter and HttpServerFilter allow multiple loads: The order of execution between instances is determined by the return value of getOrder If getOrder returns the same value, the corresponding instance order is randomly determined Whether it is request or response, read the body stream, use getBodyBytes\\ (), the return value may be null (such as scenario of getting an invocation), if not null, the corresponding stream length, Obtain through getBodyBytesLength\\ (\\ ). Tips : The beforeSendRequest of HttpClientFilter is executed in the current thread of the interface call, and the afterReceiveResponse is executed in the business thread pool. The afterReceiveRequest of HttpServerFilter is executed in the business thread pool, beforeSendResponse and beforeSendResponseAsync may be executed in the business thread pool or the network thread pool. Make sure that blocking operations can not occur. The bottom layer of Java Chassis is an asynchronous framework, with frequent thread switching. When the business extends Filter, if it involves obtaining the thread context through ThreadLocal, the acquisition may be empty. For this scenario, it is recommended to use InhritableThreadLocal instead of ThreadLocal to store data, or to use extended Handler instead of Filter. 2.HttpClientFilter The system has two built-in HttpClientFilter. Note that the order value does not conflict when extending the function: org.apache.servicecomb.provider.springmvc.reference.RestTemplateCopyHeaderFilter, order value is Integer.MIN_VALUE org.apache.servicecomb.transport.rest.client.http.DefaultHttpClientFilter, order value is Integer.MAX_VALUE 2.1 Prototype public interface HttpClientFilter { int getOrder(); void beforeSendRequest(Invocation invocation, HttpServletRequestEx requestEx); // if finished, then return a none null response // if return a null response, then sdk will call next filter.afterReceive Response afterReceiveResponse(Invocation invocation, HttpServletResponseEx responseEx); } 2.2 beforeSendRequest Used to send a request after the stream has been generated calculate the signature based on url, header, query, and stream then set to the header \\ (requestEx.setHeader). From the invocation, you can get the various metadata and the object parameters of this call (the stream is generated according to these parameters). 2.3 afterReceiveResponse Used to calculate the signature according to the header and the stream after receiving the response from the network, and compare it with the signature in the header. If the signature is incorrect, directly construct a Response. As a return value, the framework will interrupt calls to other HttpClientFilters as long as it does not return NULL. 3 HttpServerFilter 3.1 Prototype public interface HttpServerFilter { int getOrder(); default boolean needCacheRequest(OperationMeta operationMeta) { return false; } // if finished, then return a none null response // if return a null response, then sdk will call next filter.afterReceiveRequest Response afterReceiveRequest(Invocation invocation, HttpServletRequestEx requestEx); // invocation maybe null void beforeSendResponse(Invocation invocation, HttpServletResponseEx responseEx); } 3.2 needCacheRequest Unlike HttpClientFilter, the ability to decide whether to cache requests is added. This is because ServiceComb can not only run in standalone mode but also run in web container (such as Tomcat). In the implementation of a servlet, request stream can only be read once, and does not necessarily support reset (such as Tomcat), RESTful The framework needs to perform deserialization. It needs to read the body stream. The signature logic also needs to read the body stream. If the default processing is used, one of the functions cannot be implemented. So when running in a web container scenario, all HttpServerFilters, as long as there is a return request that needs to be cached, the body stream will be copied and saved to support repeated reads. The input parameter is the metadata corresponding to the request, and the service can decide whether the cache request is needed for the request. 3.3 afterReceiveRequest After receiving the request, the signature is calculated according to the URL, header, query, and code stream, and compared with the signature in the header. If the signature is incorrect, a Response is directly constructed as the return value. As long as the NULL is not returned, the framework will interrupt the other HttpClientFilter Call. 3.4 beforeSendResponse Before sending a response, the signature is calculated according to the header and the stream and set to the header. Because the invocation has not yet been constructed, the call flow has gone wrong, so the invocation may be null.","title":"Http Filter"},{"location":"general-development/http-filter/#1-overview","text":"The Filter mechanism is loaded using the Java standard SPI mechanism. Both HttpClientFilter and HttpServerFilter allow multiple loads: The order of execution between instances is determined by the return value of getOrder If getOrder returns the same value, the corresponding instance order is randomly determined Whether it is request or response, read the body stream, use getBodyBytes\\ (), the return value may be null (such as scenario of getting an invocation), if not null, the corresponding stream length, Obtain through getBodyBytesLength\\ (\\ ). Tips : The beforeSendRequest of HttpClientFilter is executed in the current thread of the interface call, and the afterReceiveResponse is executed in the business thread pool. The afterReceiveRequest of HttpServerFilter is executed in the business thread pool, beforeSendResponse and beforeSendResponseAsync may be executed in the business thread pool or the network thread pool. Make sure that blocking operations can not occur. The bottom layer of Java Chassis is an asynchronous framework, with frequent thread switching. When the business extends Filter, if it involves obtaining the thread context through ThreadLocal, the acquisition may be empty. For this scenario, it is recommended to use InhritableThreadLocal instead of ThreadLocal to store data, or to use extended Handler instead of Filter.","title":"1 Overview"},{"location":"general-development/http-filter/#2httpclientfilter","text":"The system has two built-in HttpClientFilter. Note that the order value does not conflict when extending the function: org.apache.servicecomb.provider.springmvc.reference.RestTemplateCopyHeaderFilter, order value is Integer.MIN_VALUE org.apache.servicecomb.transport.rest.client.http.DefaultHttpClientFilter, order value is Integer.MAX_VALUE","title":"2.HttpClientFilter"},{"location":"general-development/http-filter/#21-prototype","text":"public interface HttpClientFilter { int getOrder(); void beforeSendRequest(Invocation invocation, HttpServletRequestEx requestEx); // if finished, then return a none null response // if return a null response, then sdk will call next filter.afterReceive Response afterReceiveResponse(Invocation invocation, HttpServletResponseEx responseEx); }","title":"2.1 Prototype"},{"location":"general-development/http-filter/#22-beforesendrequest","text":"Used to send a request after the stream has been generated calculate the signature based on url, header, query, and stream then set to the header \\ (requestEx.setHeader). From the invocation, you can get the various metadata and the object parameters of this call (the stream is generated according to these parameters).","title":"2.2 beforeSendRequest"},{"location":"general-development/http-filter/#23-afterreceiveresponse","text":"Used to calculate the signature according to the header and the stream after receiving the response from the network, and compare it with the signature in the header. If the signature is incorrect, directly construct a Response. As a return value, the framework will interrupt calls to other HttpClientFilters as long as it does not return NULL.","title":"2.3 afterReceiveResponse"},{"location":"general-development/http-filter/#3-httpserverfilter","text":"","title":"3 HttpServerFilter"},{"location":"general-development/http-filter/#31-prototype","text":"public interface HttpServerFilter { int getOrder(); default boolean needCacheRequest(OperationMeta operationMeta) { return false; } // if finished, then return a none null response // if return a null response, then sdk will call next filter.afterReceiveRequest Response afterReceiveRequest(Invocation invocation, HttpServletRequestEx requestEx); // invocation maybe null void beforeSendResponse(Invocation invocation, HttpServletResponseEx responseEx); }","title":"3.1 Prototype"},{"location":"general-development/http-filter/#32-needcacherequest","text":"Unlike HttpClientFilter, the ability to decide whether to cache requests is added. This is because ServiceComb can not only run in standalone mode but also run in web container (such as Tomcat). In the implementation of a servlet, request stream can only be read once, and does not necessarily support reset (such as Tomcat), RESTful The framework needs to perform deserialization. It needs to read the body stream. The signature logic also needs to read the body stream. If the default processing is used, one of the functions cannot be implemented. So when running in a web container scenario, all HttpServerFilters, as long as there is a return request that needs to be cached, the body stream will be copied and saved to support repeated reads. The input parameter is the metadata corresponding to the request, and the service can decide whether the cache request is needed for the request.","title":"3.2 needCacheRequest"},{"location":"general-development/http-filter/#33-afterreceiverequest","text":"After receiving the request, the signature is calculated according to the URL, header, query, and code stream, and compared with the signature in the header. If the signature is incorrect, a Response is directly constructed as the return value. As long as the NULL is not returned, the framework will interrupt the other HttpClientFilter Call.","title":"3.3 afterReceiveRequest"},{"location":"general-development/http-filter/#34-beforesendresponse","text":"Before sending a response, the signature is calculated according to the header and the stream and set to the header. Because the invocation has not yet been constructed, the call flow has gone wrong, so the invocation may be null.","title":"3.4 beforeSendResponse"},{"location":"general-development/kuang-jia-shang-bao-ban-ben-hao/","text":"","title":"Kuang jia shang bao ban ben hao"},{"location":"general-development/local-develop-test/","text":"Local Development and Test Concept Description This section describes how developers can locally develop and commission consumer and provider applications. Both service providers and consumers need to connect to the remote service center. Two methods of building Local ServiceCenter for local microservice commissioning are as follows: Starting Local Service Center . Starting Local Service Center Mock mechanism . Local debugging by setting up environmental information The Service Center is an important component in the microservice architecture, this is used in managing and handle: registering and discovering, for service metadata and service instance metadata. The logic relationship between the service center and microservice provider/consumer is as follows: Starting Local ServiceCenter Step 1 Starting local service center run in executable files Windows Linux (1) Download the [Service Registry Executable Compressor] (http://apache.org/dyn/closer.cgi/incubator/servicecomb/incubator-servicecomb-service-center/1.0.0-m1/apache-servicecomb- Incubating-service-center-1.0.0-m1-windows-amd64.tar.gz) (2) Extract to the current folder (3) Go to the unzipped directory and double-click to run the **start-service-center.bat** file. 1) Download the Service Registry executable file archive and extract it ```bash wget http://apache.org/dyn/closer.cgi/incubator/servicecomb/incubator-servicecomb-service-center/1.0.0-m1/apache-servicecomb-incubating-service-center-1.0.0-m1-linux-amd64.tar.gz tar xvf apache-servicecomb-incubating-service-center-1.0.0-m1-linux-amd64.tar.gz ``` 2) Run the service registry ```bash Bash apache-servicecomb-incubating-service-center-1.0.0-m1-linux-amd64/start-service-center.sh ``` Note: The frontend (frontend) will be bound to the ipv6 address by default in the Linux environment, causing the browser to report an error. The repair method is: first modify the httpaddr in conf/app.conf to the external reachable network card ip, and then modify the app/appList/apiList. .js `ip : 'http://127.0.0.1'` for the corresponding ip, and finally restart ServiceCenter. Note: Both Windows and Linux versions only support 64-bit systems. Run as Docker bash Docker pull servicecomb/service-center Docker run -d -p 30100:30100 servicecomb/service-center:latest Step 2 After starting the local service center, configure the ServerCenter address and port in the service provider/consumer's microservice.yaml file. Example code: yaml Servicecomb: Service: Registry: Address: #Service Center address and port Http://127.0.0.1:30100 Step 3 Development service provider/consumer, launch microservices for local testing. ----End Mock mechanism start service center Simulate a service center that can only be used by this process in the process memory, which is generally used in the test scenario. * ### In-process call Just declare it before starting the ServiceComb engine to enable it: System.setProperty(\"local.registry.file\", \"notExistJustForceLocal\"); Cross-process call If the deployment is simple and the deployment information is static, you can use this mock mechanism even if you have a cross-process call. The producer end is still declared like \"in-process call\" However, because the Mock does not work across processes, the Mock on the consumer side needs to provide a local configuration file that describes the details of the call target, including the name, version, address, schema id, etc. Similarly, because the Mock cannot cross processes, the consumer cannot dynamically obtain the contract information of the producer. Therefore, the contract file needs to be provided locally. (This scenario, using the Mock Service Center, is much more costly than using a standalone service center, not recommended) Step 1 Create a new local service center definition file, assuming the name is registry.yaml, the content example is as follows: Step 1 Create a new local service center definition file, assuming the name is registry.yaml, the content example is as follows: yaml localserv: - id: \"100\" version: \"0.0.1\" appid: localservreg schemaIds: - hello instances: - endpoints: - rest://localhost:8080 - highway://localhost:7070 * Step 2 consumer local deployment contract file Reference: [Define Service Contract] (https://docs.servicecomb.io/java-chassis/zh_CN/build-provider/define-contract.html) * Step 3 In the consumer main function, declare the ServiceComb engine before starting: java \u3000\u3000System.setProperty(\"local.registry.file\", \"/path/registry.yaml\"); The second parameter of setProperty fills in the absolute path of the registry.yaml system on the disk, pay attention to distinguish the corresponding path separator in different systems. Local debugging by setting environment information The java chassis is strictly dependent on the contract when designing, so usually the version of the microservice has to change when the contract updated. However, if the development mode is still in progress, it is normal to modify the interface. If you need to change the version every time, it is very unfriendly to the user, so an environment setting is added for this case. If the microservice is configured as a development environment, the interface is modified (the schema has changed), and the restart can be registered to the service center without modifying the version number. However, if consumer client has already called the service before the restart, the consumer client needs to be restarted to get the latest schema. For example, A -> B, B interface has been modified and restarted, then A is still using B last schema at this time, the call may be wrong, so as to avoid unknown exceptions, A also needs to restart. There are three ways to set it up, Recommended method 1 Method 1: Set by the JVM startup parameter -Dservice_description.environment=development Method 2: Specify by microservice.yaml configuration file service_description: environment: development Method 3: Specify by environment variable (only for Windows system), such as the following settings under Eclipse","title":"Local development and testing"},{"location":"general-development/local-develop-test/#local-development-and-test","text":"","title":"Local Development and Test"},{"location":"general-development/local-develop-test/#concept-description","text":"This section describes how developers can locally develop and commission consumer and provider applications. Both service providers and consumers need to connect to the remote service center. Two methods of building Local ServiceCenter for local microservice commissioning are as follows: Starting Local Service Center . Starting Local Service Center Mock mechanism .","title":"Concept Description"},{"location":"general-development/local-develop-test/#local-debugging-by-setting-up-environmental-information","text":"The Service Center is an important component in the microservice architecture, this is used in managing and handle: registering and discovering, for service metadata and service instance metadata. The logic relationship between the service center and microservice provider/consumer is as follows:","title":"Local debugging by setting up environmental information"},{"location":"general-development/local-develop-test/#starting-local-servicecenter","text":"Step 1 Starting local service center run in executable files Windows Linux (1) Download the [Service Registry Executable Compressor] (http://apache.org/dyn/closer.cgi/incubator/servicecomb/incubator-servicecomb-service-center/1.0.0-m1/apache-servicecomb- Incubating-service-center-1.0.0-m1-windows-amd64.tar.gz) (2) Extract to the current folder (3) Go to the unzipped directory and double-click to run the **start-service-center.bat** file. 1) Download the Service Registry executable file archive and extract it ```bash wget http://apache.org/dyn/closer.cgi/incubator/servicecomb/incubator-servicecomb-service-center/1.0.0-m1/apache-servicecomb-incubating-service-center-1.0.0-m1-linux-amd64.tar.gz tar xvf apache-servicecomb-incubating-service-center-1.0.0-m1-linux-amd64.tar.gz ``` 2) Run the service registry ```bash Bash apache-servicecomb-incubating-service-center-1.0.0-m1-linux-amd64/start-service-center.sh ``` Note: The frontend (frontend) will be bound to the ipv6 address by default in the Linux environment, causing the browser to report an error. The repair method is: first modify the httpaddr in conf/app.conf to the external reachable network card ip, and then modify the app/appList/apiList. .js `ip : 'http://127.0.0.1'` for the corresponding ip, and finally restart ServiceCenter. Note: Both Windows and Linux versions only support 64-bit systems. Run as Docker bash Docker pull servicecomb/service-center Docker run -d -p 30100:30100 servicecomb/service-center:latest Step 2 After starting the local service center, configure the ServerCenter address and port in the service provider/consumer's microservice.yaml file. Example code: yaml Servicecomb: Service: Registry: Address: #Service Center address and port Http://127.0.0.1:30100 Step 3 Development service provider/consumer, launch microservices for local testing. ----End","title":"Starting Local ServiceCenter"},{"location":"general-development/local-develop-test/#mock-mechanism-start-service-center","text":"Simulate a service center that can only be used by this process in the process memory, which is generally used in the test scenario. * ### In-process call Just declare it before starting the ServiceComb engine to enable it: System.setProperty(\"local.registry.file\", \"notExistJustForceLocal\");","title":"Mock mechanism start service center"},{"location":"general-development/local-develop-test/#cross-process-call","text":"If the deployment is simple and the deployment information is static, you can use this mock mechanism even if you have a cross-process call. The producer end is still declared like \"in-process call\" However, because the Mock does not work across processes, the Mock on the consumer side needs to provide a local configuration file that describes the details of the call target, including the name, version, address, schema id, etc. Similarly, because the Mock cannot cross processes, the consumer cannot dynamically obtain the contract information of the producer. Therefore, the contract file needs to be provided locally. (This scenario, using the Mock Service Center, is much more costly than using a standalone service center, not recommended) Step 1 Create a new local service center definition file, assuming the name is registry.yaml, the content example is as follows: Step 1 Create a new local service center definition file, assuming the name is registry.yaml, the content example is as follows: yaml localserv: - id: \"100\" version: \"0.0.1\" appid: localservreg schemaIds: - hello instances: - endpoints: - rest://localhost:8080 - highway://localhost:7070 * Step 2 consumer local deployment contract file Reference: [Define Service Contract] (https://docs.servicecomb.io/java-chassis/zh_CN/build-provider/define-contract.html) * Step 3 In the consumer main function, declare the ServiceComb engine before starting: java \u3000\u3000System.setProperty(\"local.registry.file\", \"/path/registry.yaml\"); The second parameter of setProperty fills in the absolute path of the registry.yaml system on the disk, pay attention to distinguish the corresponding path separator in different systems.","title":"Cross-process call"},{"location":"general-development/local-develop-test/#local-debugging-by-setting-environment-information","text":"The java chassis is strictly dependent on the contract when designing, so usually the version of the microservice has to change when the contract updated. However, if the development mode is still in progress, it is normal to modify the interface. If you need to change the version every time, it is very unfriendly to the user, so an environment setting is added for this case. If the microservice is configured as a development environment, the interface is modified (the schema has changed), and the restart can be registered to the service center without modifying the version number. However, if consumer client has already called the service before the restart, the consumer client needs to be restarted to get the latest schema. For example, A -> B, B interface has been modified and restarted, then A is still using B last schema at this time, the call may be wrong, so as to avoid unknown exceptions, A also needs to restart. There are three ways to set it up, Recommended method 1 Method 1: Set by the JVM startup parameter -Dservice_description.environment=development Method 2: Specify by microservice.yaml configuration file service_description: environment: development Method 3: Specify by environment variable (only for Windows system), such as the following settings under Eclipse","title":"Local debugging by setting environment information"},{"location":"general-development/metrics/","text":"First, the introduction of Metrics Based on netflix spectator Foundation-metrics loads all MetricsInitializer implementations via the SPI mechanism. Implementers can use the getOrder in the MetricsInitializer to plan the execution order. The smaller the order number, the earlier it will be executed. Metrics-core implements 3 types of MetricsInitializer: DefaultRegistryInitializer: Instantiate and register spectator-reg-servo, set a smaller order, and ensure that it is executed before the following two types of MetricsInitializer Meters Initializer: Statistics of data such as TPS, delay, thread pool, jvm resources, etc. Publisher: Output statistics, built-in log output, and output via RESTful interface Metrics-prometheus provides the ability to interface with prometheus Second, how to use. 1.Maven dependence. <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>metrics-core</artifactId> </dependency> If integrate with prometheus, also need to add dependencies. <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>metrics-prometheus</artifactId> </dependency> Note: Please change the version field to the actual version number; if the version number has been declared in the dependencyManagement, then you do not have to write the version number here 2. Configuration instructions Configuration Item Default Meaning servicecomb.metrics.window_time 60000 Statistical period, in milliseconds TPS, delay, etc. Periodic data, updated once per cycle, the value obtained in the cycle, actually the value of the previous cycle servicecomb.metrics .invocation.latencyDistribution The latency distribution time period definition in milliseconds for example:0,1,10,100,1000 indicates that the following latency scopes are defined: [0, 1),[1, 10),[10, 100),[100, 1000),[1000, ) servicecomb.metrics .Consumer.invocation.slow.enabled false Whether to enable slow call detection on the Consumer side Level 4 priority definitions can be supported by adding the suffix .${service}.${schema}.${operation} servicecomb.metrics .Consumer.invocation.slow.msTime 1000 If the latency exceeds the configured value, the log will be output immediately, and the time consumption information of the stage called this time will be recorded. Level 4 priority definitions can be supported by adding the suffix .${service}.${schema}.${operation} servicecomb.metrics .Provider.invocation.slow.enabled false Whether to enable slow call detection on the Provider side Level 4 priority definitions can be supported by adding the suffix .${service}.${schema}.${operation} servicecomb.metrics .Provider.invocation.slow.msTime 1000 If the latency exceeds the configured value, the log will be output immediately, and the time consumption information of the stage called this time will be recorded. Level 4 priority definitions can be supported by adding the suffix .${service}.${schema}.${operation} servicecomb.metrics .prometheus.address 0.0.0.0:9696 prometheus listen address servicecomb.metrics.publisher.defaultLog .enabled false Whether to output the default statistics log servicecomb.metrics.publisher.defaultLog .endpoints.client.detail.enabled false Whether to output each client endpoint statistics log, because it is related to the target ip:port number, there may be a lot of data, so the default is not output 3. Slow call detection After slow call detection is enabled, if there is a slow call, the corresponding log will be output immediately: 2019-04-02 23:01:09,103\\[WARN]\\[pool-7-thread-74]\\[5ca37935c00ff2c7-350076] - slow(40 ms) invocation, CONSUMER highway perf1.impl.syncQuery http method: GET url : /v1/syncQuery/{id}/ server : highway://192.168.0.152:7070?login=true status code: 200 total : 50.760 ms prepare : 0.0 ms handlers request : 0.0 ms client filters request : 0.0 ms send request : 0.5 ms get connection : 0.0 ms write to buf : 0.5 ms wait response : 50.727 ms wake consumer : 0.23 ms client filters response: 0.2 ms handlers response : 0.0 ms (SlowInvocationLogger.java:121) Where 5ca37935c00ff2c7-350076 is the structure of ${traceId}-${invocationId}, referenced by %marker in the output format of log4j2 or logback 4. Access via RESTful As long as the microservices open the rest port, use a browser to access http://ip:port/metrics. will get json data in the following format: { \"servicecomb.vertx.endpoints(address=192.168.0.124:7070,statistic=connectCount,type=client)\": 0.0, \"servicecomb.vertx.endpoints(address=192.168.0.124:7070,statistic=disconnectCount,type=client)\": 0.0, \"servicecomb.vertx.endpoints(address=192.168.0.124:7070,statistic=connections,type=client)\": 1.0, \"servicecomb.vertx.endpoints(address=192.168.0.124:7070,statistic=bytesRead,type=client)\": 508011.0, \"servicecomb.vertx.endpoints(address=192.168.0.124:7070,statistic=bytesWritten,type=client)\": 542163.0, \"servicecomb.vertx.endpoints(address=192.168.0.124:7070,statistic=queueCount,type=client)\": 0.0, \"servicecomb.vertx.endpoints(address=0.0.0.0:7070,statistic=connectCount,type=server)\": 0.0, \"servicecomb.vertx.endpoints(address=0.0.0.0:7070,statistic=disconnectCount,type=server)\": 0.0, \"servicecomb.vertx.endpoints(address=0.0.0.0:7070,statistic=connections,type=server)\": 1.0, \"servicecomb.vertx.endpoints(address=0.0.0.0:7070,statistic=bytesRead,type=server)\": 542163.0, \"servicecomb.vertx.endpoints(address=0.0.0.0:7070,statistic=bytesWritten,type=server)\": 508011.0, \"servicecomb.vertx.endpoints(address=0.0.0.0:7070,statistic=rejectByConnectionLimit,type=server)\": 0.0, \"servicecomb.vertx.endpoints(address=localhost:8080,statistic=connectCount,type=server)\": 0.0, \"servicecomb.vertx.endpoints(address=localhost:8080,statistic=disconnectCount,type=server)\": 0.0, \"servicecomb.vertx.endpoints(address=localhost:8080,statistic=connections,type=server)\": 0.0, \"servicecomb.vertx.endpoints(address=localhost:8080,statistic=bytesRead,type=server)\": 0.0, \"servicecomb.vertx.endpoints(address=localhost:8080,statistic=bytesWritten,type=server)\": 0.0, \"servicecomb.vertx.endpoints(address=localhost:8080,statistic=rejectByConnectionLimit,type=server)\": 0.0, \"threadpool.completedTaskCount(id=cse.executor.groupThreadPool-group0)\": 4320.0, \"threadpool.rejectedCount(id=cse.executor.groupThreadPool-group0)\": 0.0, \"threadpool.taskCount(id=cse.executor.groupThreadPool-group0)\": 4320.0, \"threadpool.currentThreadsBusy(id=cse.executor.groupThreadPool-group0)\": 0.0, \"threadpool.poolSize(id=cse.executor.groupThreadPool-group0)\": 4.0, \"threadpool.maxThreads(id=cse.executor.groupThreadPool-group0)\": 10.0, \"threadpool.queueSize(id=cse.executor.groupThreadPool-group0)\": 0.0, \"threadpool.corePoolSize(id=cse.executor.groupThreadPool-group0)\": 4.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,scope=[0,1),status=200,transport=highway,type=latencyDistribution)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,scope=[1,3),status=200,transport=highway,type=latencyDistribution)\": 0.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,scope=[3,10),status=200,transport=highway,type=latencyDistribution)\": 0.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,scope=[10,100),status=200,transport=highway,type=latencyDistribution)\": 0.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,scope=[100,),status=200,transport=highway,type=latencyDistribution)\": 0.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,scope=[0,1),status=200,transport=highway,type=latencyDistribution)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,scope=[1,3),status=200,transport=highway,type=latencyDistribution)\": 0.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,scope=[3,10),status=200,transport=highway,type=latencyDistribution)\": 0.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,scope=[10,100),status=200,transport=highway,type=latencyDistribution)\": 0.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,scope=[100,),status=200,transport=highway,type=latencyDistribution)\": 0.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=total,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=total,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.25269420000000004, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=total,statistic=max,status=200,transport=highway,type=stage)\": 2.7110000000000003E-4, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=handlers_request,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=handlers_request,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.0079627, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=handlers_request,statistic=max,status=200,transport=highway,type=stage)\": 1.74E-5, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=handlers_response,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=handlers_response,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.0060666, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=handlers_response,statistic=max,status=200,transport=highway,type=stage)\": 1.08E-5, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=prepare,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=prepare,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.016679600000000003, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=prepare,statistic=max,status=200,transport=highway,type=stage)\": 2.68E-5, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=queue,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=queue,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.08155480000000001, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=queue,statistic=max,status=200,transport=highway,type=stage)\": 2.1470000000000001E-4, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=execution,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=execution,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.0098285, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=execution,statistic=max,status=200,transport=highway,type=stage)\": 4.3100000000000004E-5, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=server_filters_request,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=server_filters_request,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.0170669, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=server_filters_request,statistic=max,status=200,transport=highway,type=stage)\": 3.6400000000000004E-5, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=server_filters_response,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=server_filters_response,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.0196985, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=server_filters_response,statistic=max,status=200,transport=highway,type=stage)\": 4.8100000000000004E-5, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=producer_send_response,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=producer_send_response,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.0880885, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=producer_send_response,statistic=max,status=200,transport=highway,type=stage)\": 1.049E-4, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=total,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=total,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.9796976000000001, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=total,statistic=max,status=200,transport=highway,type=stage)\": 6.720000000000001E-4, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=handlers_request,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=handlers_request,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.012601500000000002, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=handlers_request,statistic=max,status=200,transport=highway,type=stage)\": 3.5000000000000004E-5, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=handlers_response,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=handlers_response,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.0066785, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=handlers_response,statistic=max,status=200,transport=highway,type=stage)\": 3.21E-5, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=prepare,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=prepare,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.010363800000000001, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=prepare,statistic=max,status=200,transport=highway,type=stage)\": 2.85E-5, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=client_filters_request,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=client_filters_request,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.0060282, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=client_filters_request,statistic=max,status=200,transport=highway,type=stage)\": 9.2E-6, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=consumer_send_request,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=consumer_send_request,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.099984, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=consumer_send_request,statistic=max,status=200,transport=highway,type=stage)\": 1.1740000000000001E-4, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=consumer_get_connection,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=consumer_get_connection,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.006916800000000001, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=consumer_get_connection,statistic=max,status=200,transport=highway,type=stage)\": 5.83E-5, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=consumer_write_to_buf,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=consumer_write_to_buf,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.0930672, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=consumer_write_to_buf,statistic=max,status=200,transport=highway,type=stage)\": 1.1580000000000001E-4, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=consumer_wait_response,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=consumer_wait_response,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.7654931, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=consumer_wait_response,statistic=max,status=200,transport=highway,type=stage)\": 5.547E-4, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=consumer_wake_consumer,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=consumer_wake_consumer,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.0502085, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=consumer_wake_consumer,statistic=max,status=200,transport=highway,type=stage)\": 3.7370000000000003E-4, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=client_filters_response,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=client_filters_response,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.0227188, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=client_filters_response,statistic=max,status=200,transport=highway,type=stage)\": 4.0E-5 } Third, the summary of statistical items 1. CPU Name Tag keys Tag values Description os type cpu System CPU usage in the current period, Solaris mode processCpu Microservice process CPU usage in the current period, IRIX mode processCpu divided by cpu is equal to the number of system CPUs 2. NET Name Tag keys Tag values Description os type net statistic send Average number of bytes sent per second during the current period (Bps) receive Average number of bytes received per second during the current period (Bps) sendPackets Average number of packets sent per second (pps) during the current period receivePackets Average number of packets received per second (pps) during the current period interface net dev name 3. vertx client endpoints Name Tag keys Tag values Description servicecomb .vertx .endpoints type client address ${ip}:${port} server ip:port statistic connectCount Number of connections have been initiated in the current period disconnectCount Number of disconnections in the current period queueCount The number of requests in the http connection pool that are waiting to get a connection connections Current connection number bytesRead Average number of bytes received per second during the current period (Bps) Business layer statistics, relative to the data obtained from the network card, the data here does not include the size of the header For http messages, does not include http header size bytesWritten Average number of bytes sent per second during the current period (Bps) Business layer statistics, relative to the data obtained from the network card, the data here does not include the size of the header For http messages, does not include http header size 4. vertx server endpoints Name Tag keys Tag values Description servicecomb .vertx .endpoints type server address ${ip}:${port} listen ip:port statistic connectCount Number of connections are connected in the current period disconnectCount Number of disconnections in the current period rejectByConnectionLimit Number of active disconnections due to exceeding the number of connections in the current period connections Current connection number bytesRead Average number of bytes sent per second during the current period (Bps) Business layer statistics, relative to the data obtained from the network card, the data here does not include the size of the header For http messages, does not include http header size bytesWritten Average number of bytes received per second during the current period (Bps) Business layer statistics, relative to the data obtained from the network card, the data here does not include the size of the header For http messages, does not include http header size 5. Invocation latency distribution Name Tag keys Tag values Description servicecomb .invocation role CONSUMER\u3001PRODUCER\u3001EDGE Is the CONSUMER, PRODUCER or EDGE side statistics operation ${microserviceName} .${schemaId} .${operationName} Method name called transport highway or rest On which transmission channel the call is made status http status code type latencyDistribution invocation latency distribution scope [${min}, ${max}) The call count in the current period that latency is greater than or equal to min, less than max [${min},) means max is infinite 6. invocation consumer stage latency Name Tag keys Tag values Description servicecomb .invocation role CONSUMER Statistics on the CONSUMER side operation ${microserviceName} .${schemaId} .${operationName} Method name called transport highway or rest On which transmission channel the call is made status http status code type stage stage latency stage total The whole process prepare handlers_request Handler chain request process client_filters_request Http client filter chain request process Only the rest transport has this stage. consumer_send_request Send request stage, including consumer_get_connection and consumer_write_to_buf consumer_get_connection Get a connection from the connection pool consumer_write_to_buf Write data to the network buffer consumer_wait_response Waiting for the server to answer consumer_wake_consumer In the synchronization process, after receiving the response, it takes time from waking up the waiting thread to waiting for the thread to start processing the response. client_filters_response Http client filter chain response process handlers_response Handler chain response process statistic count Average number of calls per second (TPS) Count=Number of calls/period in the statistical period (seconds) totalTime In seconds totalTime=The total duration of the call in the current period (seconds) totalTime divided by count to get the average latency max In seconds Maximum latency in the current period 7. invocation producer stage latency Name Tag keys Tag values Description servicecomb .invocation role PRODUCER Statistics on the PRODUCER side operation ${microserviceName} .${schemaId} .${operationName} Method name called transport highway or rest On which transmission channel the call is made status http status code type stage stage latency stage total The whole process prepare queue Meaning only when using a thread pool Indicates the length of time the call is queued in the thread pool server_filters_request Http server filter chain request process Only the rest transport has this stage. handlers_request Handler chain request process execution Business method handlers_response Handler chain response process server_filters_response Http server filter chain response process producer_send_response Send a response statistic count Average number of calls per second (TPS) Count=Number of calls/period in the statistical period (seconds) totalTime In seconds totalTime=The total duration of the call in the current period (seconds) AverageTime divided by count to get the average latency max In seconds Maximum latency in the current period 8. invocation edge stage latency Name Tag keys Tag values Description servicecomb .invocation role EDGE EDGE statistics operation ${microserviceName} .${schemaId} .${operationName} Method name called transport highway or rest On which transmission channel the call is made status http status code type stage stage latency stage total The whole process prepare queue Meaning only when using a thread pool Indicates the length of time the call is queued in the thread pool server_filters_request Http server filter chain request process handlers_request Handler chain request process client_filters_request Http client filter chain request process consumer_send_request Send request stage, including consumer_get_connection and consumer_write_to_buf consumer_get_connection Get a connection from the connection pool consumer_write_to_buf Write data to the network buffer consumer_wait_response Waiting for the server to answer consumer_wake_consumer In the synchronization process, after receiving the response, it takes time from waking up the waiting thread to waiting for the thread to start processing the response. client_filters_response Http client filter chain response process handlers_response Handler chain response process server_filters_response Http server filter chain response process producer_send_response Send a response statistic count Average number of calls per second (TPS) Count=Number of calls/period in the statistical period (seconds) totalTime In seconds totalTime=The total duration of the call in the current period (seconds) AverageTime divided by count to get the average latency max In seconds Maximum latency in the current period 9. threadpool Name Tag keys Tag values Description threadpool.corePoolSize id ${threadPoolName} Minimum number of threads threadpool.maxThreads Maximum number of threads allowed threadpool.poolSize Current actual number of threads threadpool.currentThreadsBusy The current number of active threads, which is the number of tasks currently being executed threadpool.queueSize Number of tasks currently queued threadpool.rejectedCount The average number of tasks rejected per second during the current period threadpool.taskCount Average number of tasks submitted per second during the statistical period taskCount=(completed + queue + active)/period (seconds) threadpool.completedTaskCount The average number of tasks completed per second during the statistical period completedTaskCount=completed/period (seconds) Fourth, business customization Because ServiceComb has initialized the registry's registry, the business no longer has to create a registry. Implement the MetricsInitializer interface, define the business-level Meters, or implement a custom Publisher, and then declare your implementation through the SPI mechanism. 1.Meters: Creating Meters capabilities is provided by spectator, available in the [netflix spectator] (https://github.com/Netflix/spectator) documentation 2.Publisher: Periodically output scenarios, such as log scenarios, subscribe to org.apache.servicecomb.foundation.metrics.PolledEvent via eventBus, PolledEvent.getMeters() is the statistical result of this cycle. Non-periodic output scenarios, such as access through the RESTful interface, the statistical results of this cycle can be obtained through globalRegistry.iterator()","title":"Metrics"},{"location":"general-development/metrics/#first-the-introduction-of-metrics","text":"Based on netflix spectator Foundation-metrics loads all MetricsInitializer implementations via the SPI mechanism. Implementers can use the getOrder in the MetricsInitializer to plan the execution order. The smaller the order number, the earlier it will be executed. Metrics-core implements 3 types of MetricsInitializer: DefaultRegistryInitializer: Instantiate and register spectator-reg-servo, set a smaller order, and ensure that it is executed before the following two types of MetricsInitializer Meters Initializer: Statistics of data such as TPS, delay, thread pool, jvm resources, etc. Publisher: Output statistics, built-in log output, and output via RESTful interface Metrics-prometheus provides the ability to interface with prometheus","title":"First, the introduction of Metrics"},{"location":"general-development/metrics/#second-how-to-use","text":"","title":"Second, how to use."},{"location":"general-development/metrics/#1maven-dependence","text":"<dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>metrics-core</artifactId> </dependency> If integrate with prometheus, also need to add dependencies. <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>metrics-prometheus</artifactId> </dependency> Note: Please change the version field to the actual version number; if the version number has been declared in the dependencyManagement, then you do not have to write the version number here","title":"1.Maven dependence."},{"location":"general-development/metrics/#2-configuration-instructions","text":"Configuration Item Default Meaning servicecomb.metrics.window_time 60000 Statistical period, in milliseconds TPS, delay, etc. Periodic data, updated once per cycle, the value obtained in the cycle, actually the value of the previous cycle servicecomb.metrics .invocation.latencyDistribution The latency distribution time period definition in milliseconds for example:0,1,10,100,1000 indicates that the following latency scopes are defined: [0, 1),[1, 10),[10, 100),[100, 1000),[1000, ) servicecomb.metrics .Consumer.invocation.slow.enabled false Whether to enable slow call detection on the Consumer side Level 4 priority definitions can be supported by adding the suffix .${service}.${schema}.${operation} servicecomb.metrics .Consumer.invocation.slow.msTime 1000 If the latency exceeds the configured value, the log will be output immediately, and the time consumption information of the stage called this time will be recorded. Level 4 priority definitions can be supported by adding the suffix .${service}.${schema}.${operation} servicecomb.metrics .Provider.invocation.slow.enabled false Whether to enable slow call detection on the Provider side Level 4 priority definitions can be supported by adding the suffix .${service}.${schema}.${operation} servicecomb.metrics .Provider.invocation.slow.msTime 1000 If the latency exceeds the configured value, the log will be output immediately, and the time consumption information of the stage called this time will be recorded. Level 4 priority definitions can be supported by adding the suffix .${service}.${schema}.${operation} servicecomb.metrics .prometheus.address 0.0.0.0:9696 prometheus listen address servicecomb.metrics.publisher.defaultLog .enabled false Whether to output the default statistics log servicecomb.metrics.publisher.defaultLog .endpoints.client.detail.enabled false Whether to output each client endpoint statistics log, because it is related to the target ip:port number, there may be a lot of data, so the default is not output","title":"2. Configuration instructions"},{"location":"general-development/metrics/#3-slow-call-detection","text":"After slow call detection is enabled, if there is a slow call, the corresponding log will be output immediately: 2019-04-02 23:01:09,103\\[WARN]\\[pool-7-thread-74]\\[5ca37935c00ff2c7-350076] - slow(40 ms) invocation, CONSUMER highway perf1.impl.syncQuery http method: GET url : /v1/syncQuery/{id}/ server : highway://192.168.0.152:7070?login=true status code: 200 total : 50.760 ms prepare : 0.0 ms handlers request : 0.0 ms client filters request : 0.0 ms send request : 0.5 ms get connection : 0.0 ms write to buf : 0.5 ms wait response : 50.727 ms wake consumer : 0.23 ms client filters response: 0.2 ms handlers response : 0.0 ms (SlowInvocationLogger.java:121) Where 5ca37935c00ff2c7-350076 is the structure of ${traceId}-${invocationId}, referenced by %marker in the output format of log4j2 or logback","title":"3. Slow call detection"},{"location":"general-development/metrics/#4-access-via-restful","text":"As long as the microservices open the rest port, use a browser to access http://ip:port/metrics. will get json data in the following format: { \"servicecomb.vertx.endpoints(address=192.168.0.124:7070,statistic=connectCount,type=client)\": 0.0, \"servicecomb.vertx.endpoints(address=192.168.0.124:7070,statistic=disconnectCount,type=client)\": 0.0, \"servicecomb.vertx.endpoints(address=192.168.0.124:7070,statistic=connections,type=client)\": 1.0, \"servicecomb.vertx.endpoints(address=192.168.0.124:7070,statistic=bytesRead,type=client)\": 508011.0, \"servicecomb.vertx.endpoints(address=192.168.0.124:7070,statistic=bytesWritten,type=client)\": 542163.0, \"servicecomb.vertx.endpoints(address=192.168.0.124:7070,statistic=queueCount,type=client)\": 0.0, \"servicecomb.vertx.endpoints(address=0.0.0.0:7070,statistic=connectCount,type=server)\": 0.0, \"servicecomb.vertx.endpoints(address=0.0.0.0:7070,statistic=disconnectCount,type=server)\": 0.0, \"servicecomb.vertx.endpoints(address=0.0.0.0:7070,statistic=connections,type=server)\": 1.0, \"servicecomb.vertx.endpoints(address=0.0.0.0:7070,statistic=bytesRead,type=server)\": 542163.0, \"servicecomb.vertx.endpoints(address=0.0.0.0:7070,statistic=bytesWritten,type=server)\": 508011.0, \"servicecomb.vertx.endpoints(address=0.0.0.0:7070,statistic=rejectByConnectionLimit,type=server)\": 0.0, \"servicecomb.vertx.endpoints(address=localhost:8080,statistic=connectCount,type=server)\": 0.0, \"servicecomb.vertx.endpoints(address=localhost:8080,statistic=disconnectCount,type=server)\": 0.0, \"servicecomb.vertx.endpoints(address=localhost:8080,statistic=connections,type=server)\": 0.0, \"servicecomb.vertx.endpoints(address=localhost:8080,statistic=bytesRead,type=server)\": 0.0, \"servicecomb.vertx.endpoints(address=localhost:8080,statistic=bytesWritten,type=server)\": 0.0, \"servicecomb.vertx.endpoints(address=localhost:8080,statistic=rejectByConnectionLimit,type=server)\": 0.0, \"threadpool.completedTaskCount(id=cse.executor.groupThreadPool-group0)\": 4320.0, \"threadpool.rejectedCount(id=cse.executor.groupThreadPool-group0)\": 0.0, \"threadpool.taskCount(id=cse.executor.groupThreadPool-group0)\": 4320.0, \"threadpool.currentThreadsBusy(id=cse.executor.groupThreadPool-group0)\": 0.0, \"threadpool.poolSize(id=cse.executor.groupThreadPool-group0)\": 4.0, \"threadpool.maxThreads(id=cse.executor.groupThreadPool-group0)\": 10.0, \"threadpool.queueSize(id=cse.executor.groupThreadPool-group0)\": 0.0, \"threadpool.corePoolSize(id=cse.executor.groupThreadPool-group0)\": 4.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,scope=[0,1),status=200,transport=highway,type=latencyDistribution)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,scope=[1,3),status=200,transport=highway,type=latencyDistribution)\": 0.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,scope=[3,10),status=200,transport=highway,type=latencyDistribution)\": 0.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,scope=[10,100),status=200,transport=highway,type=latencyDistribution)\": 0.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,scope=[100,),status=200,transport=highway,type=latencyDistribution)\": 0.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,scope=[0,1),status=200,transport=highway,type=latencyDistribution)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,scope=[1,3),status=200,transport=highway,type=latencyDistribution)\": 0.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,scope=[3,10),status=200,transport=highway,type=latencyDistribution)\": 0.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,scope=[10,100),status=200,transport=highway,type=latencyDistribution)\": 0.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,scope=[100,),status=200,transport=highway,type=latencyDistribution)\": 0.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=total,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=total,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.25269420000000004, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=total,statistic=max,status=200,transport=highway,type=stage)\": 2.7110000000000003E-4, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=handlers_request,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=handlers_request,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.0079627, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=handlers_request,statistic=max,status=200,transport=highway,type=stage)\": 1.74E-5, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=handlers_response,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=handlers_response,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.0060666, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=handlers_response,statistic=max,status=200,transport=highway,type=stage)\": 1.08E-5, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=prepare,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=prepare,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.016679600000000003, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=prepare,statistic=max,status=200,transport=highway,type=stage)\": 2.68E-5, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=queue,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=queue,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.08155480000000001, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=queue,statistic=max,status=200,transport=highway,type=stage)\": 2.1470000000000001E-4, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=execution,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=execution,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.0098285, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=execution,statistic=max,status=200,transport=highway,type=stage)\": 4.3100000000000004E-5, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=server_filters_request,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=server_filters_request,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.0170669, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=server_filters_request,statistic=max,status=200,transport=highway,type=stage)\": 3.6400000000000004E-5, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=server_filters_response,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=server_filters_response,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.0196985, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=server_filters_response,statistic=max,status=200,transport=highway,type=stage)\": 4.8100000000000004E-5, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=producer_send_response,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=producer_send_response,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.0880885, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=PRODUCER,stage=producer_send_response,statistic=max,status=200,transport=highway,type=stage)\": 1.049E-4, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=total,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=total,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.9796976000000001, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=total,statistic=max,status=200,transport=highway,type=stage)\": 6.720000000000001E-4, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=handlers_request,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=handlers_request,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.012601500000000002, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=handlers_request,statistic=max,status=200,transport=highway,type=stage)\": 3.5000000000000004E-5, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=handlers_response,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=handlers_response,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.0066785, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=handlers_response,statistic=max,status=200,transport=highway,type=stage)\": 3.21E-5, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=prepare,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=prepare,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.010363800000000001, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=prepare,statistic=max,status=200,transport=highway,type=stage)\": 2.85E-5, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=client_filters_request,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=client_filters_request,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.0060282, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=client_filters_request,statistic=max,status=200,transport=highway,type=stage)\": 9.2E-6, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=consumer_send_request,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=consumer_send_request,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.099984, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=consumer_send_request,statistic=max,status=200,transport=highway,type=stage)\": 1.1740000000000001E-4, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=consumer_get_connection,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=consumer_get_connection,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.006916800000000001, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=consumer_get_connection,statistic=max,status=200,transport=highway,type=stage)\": 5.83E-5, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=consumer_write_to_buf,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=consumer_write_to_buf,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.0930672, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=consumer_write_to_buf,statistic=max,status=200,transport=highway,type=stage)\": 1.1580000000000001E-4, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=consumer_wait_response,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=consumer_wait_response,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.7654931, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=consumer_wait_response,statistic=max,status=200,transport=highway,type=stage)\": 5.547E-4, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=consumer_wake_consumer,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=consumer_wake_consumer,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.0502085, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=consumer_wake_consumer,statistic=max,status=200,transport=highway,type=stage)\": 3.7370000000000003E-4, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=client_filters_response,statistic=count,status=200,transport=highway,type=stage)\": 4269.0, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=client_filters_response,statistic=totalTime,status=200,transport=highway,type=stage)\": 0.0227188, \"servicecomb.invocation(operation=perf1.impl.syncQuery,role=CONSUMER,stage=client_filters_response,statistic=max,status=200,transport=highway,type=stage)\": 4.0E-5 }","title":"4. Access via RESTful"},{"location":"general-development/metrics/#third-the-summary-of-statistical-items","text":"","title":"Third, the summary of statistical items"},{"location":"general-development/metrics/#1-cpu","text":"Name Tag keys Tag values Description os type cpu System CPU usage in the current period, Solaris mode processCpu Microservice process CPU usage in the current period, IRIX mode processCpu divided by cpu is equal to the number of system CPUs","title":"1. CPU"},{"location":"general-development/metrics/#2-net","text":"Name Tag keys Tag values Description os type net statistic send Average number of bytes sent per second during the current period (Bps) receive Average number of bytes received per second during the current period (Bps) sendPackets Average number of packets sent per second (pps) during the current period receivePackets Average number of packets received per second (pps) during the current period interface net dev name","title":"2. NET"},{"location":"general-development/metrics/#3-vertx-client-endpoints","text":"Name Tag keys Tag values Description servicecomb .vertx .endpoints type client address ${ip}:${port} server ip:port statistic connectCount Number of connections have been initiated in the current period disconnectCount Number of disconnections in the current period queueCount The number of requests in the http connection pool that are waiting to get a connection connections Current connection number bytesRead Average number of bytes received per second during the current period (Bps) Business layer statistics, relative to the data obtained from the network card, the data here does not include the size of the header For http messages, does not include http header size bytesWritten Average number of bytes sent per second during the current period (Bps) Business layer statistics, relative to the data obtained from the network card, the data here does not include the size of the header For http messages, does not include http header size","title":"3. vertx client endpoints"},{"location":"general-development/metrics/#4-vertx-server-endpoints","text":"Name Tag keys Tag values Description servicecomb .vertx .endpoints type server address ${ip}:${port} listen ip:port statistic connectCount Number of connections are connected in the current period disconnectCount Number of disconnections in the current period rejectByConnectionLimit Number of active disconnections due to exceeding the number of connections in the current period connections Current connection number bytesRead Average number of bytes sent per second during the current period (Bps) Business layer statistics, relative to the data obtained from the network card, the data here does not include the size of the header For http messages, does not include http header size bytesWritten Average number of bytes received per second during the current period (Bps) Business layer statistics, relative to the data obtained from the network card, the data here does not include the size of the header For http messages, does not include http header size","title":"4. vertx server endpoints"},{"location":"general-development/metrics/#5-invocation-latency-distribution","text":"Name Tag keys Tag values Description servicecomb .invocation role CONSUMER\u3001PRODUCER\u3001EDGE Is the CONSUMER, PRODUCER or EDGE side statistics operation ${microserviceName} .${schemaId} .${operationName} Method name called transport highway or rest On which transmission channel the call is made status http status code type latencyDistribution invocation latency distribution scope [${min}, ${max}) The call count in the current period that latency is greater than or equal to min, less than max [${min},) means max is infinite","title":"5. Invocation latency distribution"},{"location":"general-development/metrics/#6-invocation-consumer-stage-latency","text":"Name Tag keys Tag values Description servicecomb .invocation role CONSUMER Statistics on the CONSUMER side operation ${microserviceName} .${schemaId} .${operationName} Method name called transport highway or rest On which transmission channel the call is made status http status code type stage stage latency stage total The whole process prepare handlers_request Handler chain request process client_filters_request Http client filter chain request process Only the rest transport has this stage. consumer_send_request Send request stage, including consumer_get_connection and consumer_write_to_buf consumer_get_connection Get a connection from the connection pool consumer_write_to_buf Write data to the network buffer consumer_wait_response Waiting for the server to answer consumer_wake_consumer In the synchronization process, after receiving the response, it takes time from waking up the waiting thread to waiting for the thread to start processing the response. client_filters_response Http client filter chain response process handlers_response Handler chain response process statistic count Average number of calls per second (TPS) Count=Number of calls/period in the statistical period (seconds) totalTime In seconds totalTime=The total duration of the call in the current period (seconds) totalTime divided by count to get the average latency max In seconds Maximum latency in the current period","title":"6. invocation consumer stage latency"},{"location":"general-development/metrics/#7-invocation-producer-stage-latency","text":"Name Tag keys Tag values Description servicecomb .invocation role PRODUCER Statistics on the PRODUCER side operation ${microserviceName} .${schemaId} .${operationName} Method name called transport highway or rest On which transmission channel the call is made status http status code type stage stage latency stage total The whole process prepare queue Meaning only when using a thread pool Indicates the length of time the call is queued in the thread pool server_filters_request Http server filter chain request process Only the rest transport has this stage. handlers_request Handler chain request process execution Business method handlers_response Handler chain response process server_filters_response Http server filter chain response process producer_send_response Send a response statistic count Average number of calls per second (TPS) Count=Number of calls/period in the statistical period (seconds) totalTime In seconds totalTime=The total duration of the call in the current period (seconds) AverageTime divided by count to get the average latency max In seconds Maximum latency in the current period","title":"7. invocation producer stage latency"},{"location":"general-development/metrics/#8-invocation-edge-stage-latency","text":"Name Tag keys Tag values Description servicecomb .invocation role EDGE EDGE statistics operation ${microserviceName} .${schemaId} .${operationName} Method name called transport highway or rest On which transmission channel the call is made status http status code type stage stage latency stage total The whole process prepare queue Meaning only when using a thread pool Indicates the length of time the call is queued in the thread pool server_filters_request Http server filter chain request process handlers_request Handler chain request process client_filters_request Http client filter chain request process consumer_send_request Send request stage, including consumer_get_connection and consumer_write_to_buf consumer_get_connection Get a connection from the connection pool consumer_write_to_buf Write data to the network buffer consumer_wait_response Waiting for the server to answer consumer_wake_consumer In the synchronization process, after receiving the response, it takes time from waking up the waiting thread to waiting for the thread to start processing the response. client_filters_response Http client filter chain response process handlers_response Handler chain response process server_filters_response Http server filter chain response process producer_send_response Send a response statistic count Average number of calls per second (TPS) Count=Number of calls/period in the statistical period (seconds) totalTime In seconds totalTime=The total duration of the call in the current period (seconds) AverageTime divided by count to get the average latency max In seconds Maximum latency in the current period","title":"8. invocation edge stage latency"},{"location":"general-development/metrics/#9-threadpool","text":"Name Tag keys Tag values Description threadpool.corePoolSize id ${threadPoolName} Minimum number of threads threadpool.maxThreads Maximum number of threads allowed threadpool.poolSize Current actual number of threads threadpool.currentThreadsBusy The current number of active threads, which is the number of tasks currently being executed threadpool.queueSize Number of tasks currently queued threadpool.rejectedCount The average number of tasks rejected per second during the current period threadpool.taskCount Average number of tasks submitted per second during the statistical period taskCount=(completed + queue + active)/period (seconds) threadpool.completedTaskCount The average number of tasks completed per second during the statistical period completedTaskCount=completed/period (seconds)","title":"9. threadpool"},{"location":"general-development/metrics/#fourth-business-customization","text":"Because ServiceComb has initialized the registry's registry, the business no longer has to create a registry. Implement the MetricsInitializer interface, define the business-level Meters, or implement a custom Publisher, and then declare your implementation through the SPI mechanism.","title":"Fourth, business customization"},{"location":"general-development/metrics/#1meters","text":"Creating Meters capabilities is provided by spectator, available in the [netflix spectator] (https://github.com/Netflix/spectator) documentation","title":"1.Meters:"},{"location":"general-development/metrics/#2publisher","text":"Periodically output scenarios, such as log scenarios, subscribe to org.apache.servicecomb.foundation.metrics.PolledEvent via eventBus, PolledEvent.getMeters() is the statistical result of this cycle. Non-periodic output scenarios, such as access through the RESTful interface, the statistical results of this cycle can be obtained through globalRegistry.iterator()","title":"2.Publisher:"},{"location":"general-development/microservice-invocation-chain/","text":"Concept Description The microservices architecture solves the problems of many single applications, but it also requires us to pay extra. Request processing latency due to network instability is one of the costs. In a single application, all modules run in the same process, so there is no inter-module interworking problem. However, in the micro-service architecture, services communicate through the network, so we have to deal with network-related issues such as delays, timeouts, network partitions, and so on. Also, as the business expands its services, it is difficult to see how data flows through a spider-like complex service structure. How can we effectively monitor network latency and visualize data flow in services? Distributed Call Chain Tracking is used to monitor network latency for microservices effectively and visualize data flow in microservices. Zipkin [Zipkin] (http://zipkin.io/) is a distributed call chain tracking system. It helps users collect time series data to locate latency issues in microservices, and it also manages the collection and query of trace data. Zipkin's design is based on Google [Dapper paper] (http://research.google.com/pubs/pub36356.html). ServiceComb integrates Zipkin to provide automatic call chain tracking capabilities so that users only need to focus on their business needs. Steps for usage: Adding dependencies Microservices based on ServiceComb Java Chassis only need to add the following dependency to pom.xml: <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>handler-tracing-zipkin</artifactId> </dependency> If the microservice is based on Spring Cloud + Zuul's API gateway, such as the manager service in the workshop demo, we also need to add the following additional dependencies: <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>spring-cloud-zuul-zipkin</artifactId> </dependency> Configuring Tracking Processing and Data Collection {#Configuration Tracking Processing and Data Collection} Set the tracking processor and data collection service address in the microservice.yaml file servicecomb: handler: chain: Consumer: default: tracing-consumer Provider: default: tracing-provider servicecomb: tracing: collector: address: http://zipkin.servicecomb.io:9411 In this way, with the addition of two configuration items and no changes to one line of code, we started the distributed call chain tracking function based on Zipkin and Java chassis. Note If other dependencies in the project also introduce a zipkin (such as Spring Cloud), which may cause the zipkin version to be inconsistent and run incorrectly, you need to declare the zipkin version in the project pom.","title":"Microservice invocation chain"},{"location":"general-development/microservice-invocation-chain/#concept-description","text":"The microservices architecture solves the problems of many single applications, but it also requires us to pay extra. Request processing latency due to network instability is one of the costs. In a single application, all modules run in the same process, so there is no inter-module interworking problem. However, in the micro-service architecture, services communicate through the network, so we have to deal with network-related issues such as delays, timeouts, network partitions, and so on. Also, as the business expands its services, it is difficult to see how data flows through a spider-like complex service structure. How can we effectively monitor network latency and visualize data flow in services? Distributed Call Chain Tracking is used to monitor network latency for microservices effectively and visualize data flow in microservices.","title":"Concept Description"},{"location":"general-development/microservice-invocation-chain/#zipkin","text":"[Zipkin] (http://zipkin.io/) is a distributed call chain tracking system. It helps users collect time series data to locate latency issues in microservices, and it also manages the collection and query of trace data. Zipkin's design is based on Google [Dapper paper] (http://research.google.com/pubs/pub36356.html). ServiceComb integrates Zipkin to provide automatic call chain tracking capabilities so that users only need to focus on their business needs.","title":"Zipkin"},{"location":"general-development/microservice-invocation-chain/#steps-for-usage","text":"","title":"Steps for usage:"},{"location":"general-development/microservice-invocation-chain/#adding-dependencies","text":"Microservices based on ServiceComb Java Chassis only need to add the following dependency to pom.xml: <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>handler-tracing-zipkin</artifactId> </dependency> If the microservice is based on Spring Cloud + Zuul's API gateway, such as the manager service in the workshop demo, we also need to add the following additional dependencies: <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>spring-cloud-zuul-zipkin</artifactId> </dependency>","title":"Adding dependencies"},{"location":"general-development/microservice-invocation-chain/#configuring-tracking-processing-and-data-collection-configuration-tracking-processing-and-data-collection","text":"Set the tracking processor and data collection service address in the microservice.yaml file servicecomb: handler: chain: Consumer: default: tracing-consumer Provider: default: tracing-provider servicecomb: tracing: collector: address: http://zipkin.servicecomb.io:9411 In this way, with the addition of two configuration items and no changes to one line of code, we started the distributed call chain tracking function based on Zipkin and Java chassis. Note If other dependencies in the project also introduce a zipkin (such as Spring Cloud), which may cause the zipkin version to be inconsistent and run incorrectly, you need to declare the zipkin version in the project pom.","title":"Configuring Tracking Processing and Data Collection {#Configuration Tracking Processing and Data Collection}"},{"location":"general-development/multienvironment/","text":"Multi-environment isolation between microservice instances When doing service discovery, developers need to understand that the microservice can discover instances of those other services. ServiceComb provides hierarchical instance isolation. Microservices instance hierarchical management To understand the isolation level between instances, you first need to understand a well-established microservice system structure defined by ServiceComb: In the microservice system structure, the top layer is the \u201cproject\u201d, which is divided into multiple tenants under the project. The tenant contains multiple applications, and each application contains multiple environments, that is, the test and production environments can be separated. In a particular environment of a particular application, there are multiple microservices, and one microservice can have multiple versions at the same time. The above is the scope of all static metadata. A specific version of a particular service contains multiple microservice instances registered at runtime, because the information of the service instance is dynamic at runtime because of system scaling, failure, etc. The change, so the routing information of the service instance is again dynamic data. By hierarchically managing these data for microservices, this is natural to achieve logical isolation between instances. * Project corresponds to the project created under each region of Huawei cloud. Different projects are isolated from each other. If there is no new project under the region, it represents the region; for example, create a project named tianjing in North China (cn-north-1), if you want to register the microservice to the project, you can configure it in the microservice.yaml file\uff1a servicecomb: credentials: project: cn-north-1_tianjing Environment indicates the current environment of the microservice instance. You can configure the current instance environment through service_description.environment in the microservice.yaml file. Application represents a logical entity of a software application, representing a computer software application that has a business function presented to the user. The application name can be configured in the microservice.yaml file via the APPLICATION_ID. Service is a description of the functional objects that are accessed on demand. There are multiple services under one application, and each service calls each other. The service name can be specified in the microservice.yaml file by service_description.name. Version indicates the current service version. There may be multiple versions under one service. The current microservice version can be configured in the microservice.yaml file through service_description.version. When the consumer accesses, the default access is based on the routing rule, which can set by servicecomb.references.[providerName].version-rule in consumer. Typical scene Inter-application isolation and cross-application calls Function introduction In the ServiceComb framework, an application contains multiple microservices. The same microservice instance can be deployed as a public service to multiple applications by specifying a different APPLICATION_ID. Different microservice instances, by default, are only allowed to call each other in the same application. When users need to call microservices between different applications, they need to enable cross-application calling. Configuration instructions: To enable cross-application calls, you first need to enable cross-application call configuration in the microservice.yaml file on the provider side. The configuration items are as follows: service_description: properties: allowCrossApp: true When the Consumer side specifies the microservice name to call the provider, it needs to add the application ID to which the provider belongs. The format changes from [microserviceName] to [appID]:[microserviceName]. Code example: Assume that the application to which the consumer belongs is helloApp, the application to which the provider belongs is hellApp2, and the name of the microservice is helloProvider. * RestTemplate call mode When the consumer side develops the microservice consumer in the RestTemplate mode, you need to change [microserviceName] to [appID]:[microserviceName] in the called URL, as follows: RestTemplate restTemplate = RestTemplateBuilder.create(); ResponseEntity<String> responseEntity = restTemplate.getForEntity(\u201ccse://helloApp2:helloProvider/hello/sayHello?name={name}\u201d, String.class, \u201cServiceComb\u201d); RPC call mode When the consumer side develops a microservice consumer in RPC mode, the declared service provider proxy is as follows: @RpcReference(schemaId = \u201chello\u201d, microserviceName = \u201chelloApp2:helloProvider\u201d) private Hello hello; Cross-application calls are the same as calling microservices under the same application: hello.sayHello(\u201cServiceComb\u201d); Typical scene Development environment is isolated and rapidly developed Function introduction By setting the environment, the ServiceComb framework can mark microservice instances as development, testing, acceptance, and production environments, and achieve natural isolation at the instance level. When the client looks for a server instance, it can only find server instance under the same environment. ServiceComb is strictly dependent on the contract when designing, so under normal circumstances, the contract has changed, you must modify the version of the microservice. However, if current is still development mode, then modify the interface is a very normal situation, when the modification is completed and the current service is started again, the newly generated contract and the old contract saved on the Service Center will conflict and report an error, causing the startup to fail, It is obviously unfriendly to developers by modifying the microservice version number or by deleting the cached data of the service on the Service Center each time. The ServiceComb framework supports rapid debugging of microservices in the development state by configuring the environment as development. When the interface is modified (the schema has changed), restart can be registered to the service center without modifying the version number. But if a consumer has already called the service before the restart, then the consumer side needs to be restarted to get the schema of the latest provider; for example, A->B, the B interface has been modified and restarted, then A is still using B's previous schema, The call may be in error. to avoid an unknown exception and A needs to be restarted. Configuration instructions: Only the following enumerated values are supported: development, testing, acceptance, production. If not configured, the default value is \"\" (empty). Method 1: Set by the JVM startup parameter -Dservice_description.environment=development (enumeration value); Method 2: Specify by microservice.yaml configuration file: service_description: environment: development Method 3: Specify by environment variable SERVICECOMB_ENV (only for windows system), if it is development state, its value is configured as development; Typical scene Three centers in two places Function introduction In the scenario of deploying services across regions in a three centers in two places solution, the same services exists in multiple availableZones. It is necessary to implement the application in the same AZ with priority. If there is a problem with the same AZ, it must be able to access another AZ. To ensure the reliability of the service. ServiceComb provides data center configuration to partition and manage microservices. The data center contains three attributes: servicecomb.datacenter.name, servicecomb.datacenter.region, servicecomb.datacenter.availableZone, data center information does not provide isolation capabilities, and microservices can discover instances of other data centers. However, you can prioritize sending messages to a specified zone or zone by enabling instance affinity. When the client is routing, the request will be forwarded to the instance with the same zone/region, and then the instance with the same region but different zones. When they are all different, select one according to the routing rules. Affinity is not logical isolation. As long as the network between the instances is interconnected, it is possible to access it; if the network is unreachable, the access will fail. When the cloud is deployed on the Huawei cloud, the values of the region and the availableZone can be associated with the Huawei cloud region (for example, cn-north-1) and the available region. However, because the different regions on the Huawei cloud do not communicate with each other, the network is not interconnected, so it does not support cross-region access; in addition to the region value corresponding to Huawei cloud, you can also define other values by yourself, and adjust accordingly according to the actual situation, which is very flexible. Configuration instructions: servicecomb: datacenter: name: mydatacenter region: my-Region availableZone: my-Zone","title":"Multi-environment isolation between microservice instances"},{"location":"general-development/multienvironment/#multi-environment-isolation-between-microservice-instances","text":"When doing service discovery, developers need to understand that the microservice can discover instances of those other services. ServiceComb provides hierarchical instance isolation.","title":"Multi-environment isolation between microservice instances"},{"location":"general-development/multienvironment/#microservices-instance-hierarchical-management","text":"To understand the isolation level between instances, you first need to understand a well-established microservice system structure defined by ServiceComb: In the microservice system structure, the top layer is the \u201cproject\u201d, which is divided into multiple tenants under the project. The tenant contains multiple applications, and each application contains multiple environments, that is, the test and production environments can be separated. In a particular environment of a particular application, there are multiple microservices, and one microservice can have multiple versions at the same time. The above is the scope of all static metadata. A specific version of a particular service contains multiple microservice instances registered at runtime, because the information of the service instance is dynamic at runtime because of system scaling, failure, etc. The change, so the routing information of the service instance is again dynamic data. By hierarchically managing these data for microservices, this is natural to achieve logical isolation between instances. * Project corresponds to the project created under each region of Huawei cloud. Different projects are isolated from each other. If there is no new project under the region, it represents the region; for example, create a project named tianjing in North China (cn-north-1), if you want to register the microservice to the project, you can configure it in the microservice.yaml file\uff1a servicecomb: credentials: project: cn-north-1_tianjing Environment indicates the current environment of the microservice instance. You can configure the current instance environment through service_description.environment in the microservice.yaml file. Application represents a logical entity of a software application, representing a computer software application that has a business function presented to the user. The application name can be configured in the microservice.yaml file via the APPLICATION_ID. Service is a description of the functional objects that are accessed on demand. There are multiple services under one application, and each service calls each other. The service name can be specified in the microservice.yaml file by service_description.name. Version indicates the current service version. There may be multiple versions under one service. The current microservice version can be configured in the microservice.yaml file through service_description.version. When the consumer accesses, the default access is based on the routing rule, which can set by servicecomb.references.[providerName].version-rule in consumer.","title":"Microservices instance hierarchical management"},{"location":"general-development/multienvironment/#typical-scene","text":"","title":"Typical scene"},{"location":"general-development/multienvironment/#inter-application-isolation-and-cross-application-calls","text":"","title":"Inter-application isolation and cross-application calls"},{"location":"general-development/multienvironment/#function-introduction","text":"In the ServiceComb framework, an application contains multiple microservices. The same microservice instance can be deployed as a public service to multiple applications by specifying a different APPLICATION_ID. Different microservice instances, by default, are only allowed to call each other in the same application. When users need to call microservices between different applications, they need to enable cross-application calling.","title":"Function introduction"},{"location":"general-development/multienvironment/#configuration-instructions","text":"To enable cross-application calls, you first need to enable cross-application call configuration in the microservice.yaml file on the provider side. The configuration items are as follows: service_description: properties: allowCrossApp: true When the Consumer side specifies the microservice name to call the provider, it needs to add the application ID to which the provider belongs. The format changes from [microserviceName] to [appID]:[microserviceName].","title":"Configuration instructions:"},{"location":"general-development/multienvironment/#code-example","text":"Assume that the application to which the consumer belongs is helloApp, the application to which the provider belongs is hellApp2, and the name of the microservice is helloProvider. * RestTemplate call mode When the consumer side develops the microservice consumer in the RestTemplate mode, you need to change [microserviceName] to [appID]:[microserviceName] in the called URL, as follows: RestTemplate restTemplate = RestTemplateBuilder.create(); ResponseEntity<String> responseEntity = restTemplate.getForEntity(\u201ccse://helloApp2:helloProvider/hello/sayHello?name={name}\u201d, String.class, \u201cServiceComb\u201d); RPC call mode When the consumer side develops a microservice consumer in RPC mode, the declared service provider proxy is as follows: @RpcReference(schemaId = \u201chello\u201d, microserviceName = \u201chelloApp2:helloProvider\u201d) private Hello hello; Cross-application calls are the same as calling microservices under the same application: hello.sayHello(\u201cServiceComb\u201d);","title":"Code example:"},{"location":"general-development/multienvironment/#typical-scene_1","text":"","title":"Typical scene"},{"location":"general-development/multienvironment/#development-environment-is-isolated-and-rapidly-developed","text":"","title":"Development environment is isolated and rapidly developed"},{"location":"general-development/multienvironment/#function-introduction_1","text":"By setting the environment, the ServiceComb framework can mark microservice instances as development, testing, acceptance, and production environments, and achieve natural isolation at the instance level. When the client looks for a server instance, it can only find server instance under the same environment. ServiceComb is strictly dependent on the contract when designing, so under normal circumstances, the contract has changed, you must modify the version of the microservice. However, if current is still development mode, then modify the interface is a very normal situation, when the modification is completed and the current service is started again, the newly generated contract and the old contract saved on the Service Center will conflict and report an error, causing the startup to fail, It is obviously unfriendly to developers by modifying the microservice version number or by deleting the cached data of the service on the Service Center each time. The ServiceComb framework supports rapid debugging of microservices in the development state by configuring the environment as development. When the interface is modified (the schema has changed), restart can be registered to the service center without modifying the version number. But if a consumer has already called the service before the restart, then the consumer side needs to be restarted to get the schema of the latest provider; for example, A->B, the B interface has been modified and restarted, then A is still using B's previous schema, The call may be in error. to avoid an unknown exception and A needs to be restarted.","title":"Function introduction"},{"location":"general-development/multienvironment/#configuration-instructions_1","text":"Only the following enumerated values are supported: development, testing, acceptance, production. If not configured, the default value is \"\" (empty). Method 1: Set by the JVM startup parameter -Dservice_description.environment=development (enumeration value); Method 2: Specify by microservice.yaml configuration file: service_description: environment: development Method 3: Specify by environment variable SERVICECOMB_ENV (only for windows system), if it is development state, its value is configured as development;","title":"Configuration instructions:"},{"location":"general-development/multienvironment/#typical-scene_2","text":"","title":"Typical scene"},{"location":"general-development/multienvironment/#three-centers-in-two-places","text":"","title":"Three centers in two places"},{"location":"general-development/multienvironment/#function-introduction_2","text":"In the scenario of deploying services across regions in a three centers in two places solution, the same services exists in multiple availableZones. It is necessary to implement the application in the same AZ with priority. If there is a problem with the same AZ, it must be able to access another AZ. To ensure the reliability of the service. ServiceComb provides data center configuration to partition and manage microservices. The data center contains three attributes: servicecomb.datacenter.name, servicecomb.datacenter.region, servicecomb.datacenter.availableZone, data center information does not provide isolation capabilities, and microservices can discover instances of other data centers. However, you can prioritize sending messages to a specified zone or zone by enabling instance affinity. When the client is routing, the request will be forwarded to the instance with the same zone/region, and then the instance with the same region but different zones. When they are all different, select one according to the routing rules. Affinity is not logical isolation. As long as the network between the instances is interconnected, it is possible to access it; if the network is unreachable, the access will fail. When the cloud is deployed on the Huawei cloud, the values of the region and the availableZone can be associated with the Huawei cloud region (for example, cn-north-1) and the available region. However, because the different regions on the Huawei cloud do not communicate with each other, the network is not interconnected, so it does not support cross-region access; in addition to the region value corresponding to Huawei cloud, you can also define other values by yourself, and adjust accordingly according to the actual situation, which is very flexible.","title":"Function introduction"},{"location":"general-development/multienvironment/#configuration-instructions_2","text":"servicecomb: datacenter: name: mydatacenter region: my-Region availableZone: my-Zone","title":"Configuration instructions:"},{"location":"general-development/produceprocess/","text":"return value serialization extension Concept Description The current REST channel return value supports both application/json and text/plain formats, supports developer extensions and rewrites, service providers provide serialization capabilities through producer declarations, and service consumers specify return value serialization through the request's Accept header. By default, the data in application/json format is returned. Development Instructions extension Developers can extend the return value serialization method programmatically based on business needs. The implementation steps are as follows, taking the extended support application/xml format as an example: 1. Implement the interface ProduceProcessor . > getName() returns the current extended data type name > > getOrder() returns the current data type priority. It has multiple implementation classes with the same name. It only loads the highest priority. The smaller the number, the higher the priority. > > doEncodeResponse(OutputStream output, Object result) encodes the result object into output, where the logic needs to be implemented by itself. > > doDecodeResponse(InputStream input, JavaType type) parses the input into the corresponding object, where the logic needs to be implemented by itself. ```java public class ProduceAppXmlProcessor implements ProduceProcessor { @Override public String getName() { return MediaType.APPLICATION_XML; } @Override public int getOrder() { return 0; } @Override public void doEncodeResponse(OutputStream output, Object result) throws Exception { output.write(JAXBUtils.convertToXml(result).getBytes()); } @Override public Object doDecodeResponse(InputStream input, JavaType type) throws Exception { return JAXBUtils.convertToJavaBean(input, type); } } ``` 2. Add a configuration file In the META-INF/services/ folder under resources, create a new file xxx.ProduceProcessor (xxx is the package name of the interface), and fill in the content xxx.ProduceAppXmlProcessor (xxx is the package name of the implementation class). Rewrite Developers can rewrite the existing application/json and text/plain implementation logic, or rewrite the self-extended format to rewrite the xml serialization method as an example: 1. Create a class named 'ProduceAppXmlProcessor with the same name to implement the interface ProduceProcessor`. 2. Rewrite the codec logic in the doEncodeResponse and doDecodeResponse methods 3. Change the return value in the getOrder method, which is smaller than the return value of the original method. For example, return -1, the original method return value of application/json and text/plain defaults to 0. 4. In the META-INF/services/ folder under resources, create a new file xxx.ProduceProcessor (xxx is the package name of the interface), and fill in the content xxx.ProduceAppXmlProcessor (xxx is the package name of the implementation class). verification Service providers provide xml serialization capabilities through producer declarations java @RequestMapping(path = \"/appXml\", method = RequestMethod.POST, produces = MediaType.APPLICATION_XML_VALUE) public JAXBPerson appXml(@RequestBody JAXBPerson person) { return person; } The service consumer indicates the return value xml serialization mode through the request's Accept header. java private void testCodeFirstAppXml(RestTemplate template, String cseUrlPrefix) { JAXBPerson person = new JAXBPerson(\"jake\", 22, \"it\", \"60kg\"); person.setJob(new JAXBJob(\"developer\", \"coding\")); HttpHeaders headers = new HttpHeaders(); headers.add(\"Accept\", MediaType.APPLICATION_XML_VALUE); HttpEntity<JAXBPerson> requestEntity = new HttpEntity<>(person, headers); ResponseEntity<JAXBPerson> resEntity = template.exchange(cseUrlPrefix + \"appXml\", HttpMethod.POST, requestEntity, JAXBPerson.class); TestMgr.check(person, resEntity.getBody()); }","title":"Return value serialization extension"},{"location":"general-development/produceprocess/#return-value-serialization-extension","text":"","title":"return value serialization extension"},{"location":"general-development/produceprocess/#concept-description","text":"The current REST channel return value supports both application/json and text/plain formats, supports developer extensions and rewrites, service providers provide serialization capabilities through producer declarations, and service consumers specify return value serialization through the request's Accept header. By default, the data in application/json format is returned.","title":"Concept Description"},{"location":"general-development/produceprocess/#development-instructions","text":"","title":"Development Instructions"},{"location":"general-development/produceprocess/#extension","text":"Developers can extend the return value serialization method programmatically based on business needs. The implementation steps are as follows, taking the extended support application/xml format as an example: 1. Implement the interface ProduceProcessor . > getName() returns the current extended data type name > > getOrder() returns the current data type priority. It has multiple implementation classes with the same name. It only loads the highest priority. The smaller the number, the higher the priority. > > doEncodeResponse(OutputStream output, Object result) encodes the result object into output, where the logic needs to be implemented by itself. > > doDecodeResponse(InputStream input, JavaType type) parses the input into the corresponding object, where the logic needs to be implemented by itself. ```java public class ProduceAppXmlProcessor implements ProduceProcessor { @Override public String getName() { return MediaType.APPLICATION_XML; } @Override public int getOrder() { return 0; } @Override public void doEncodeResponse(OutputStream output, Object result) throws Exception { output.write(JAXBUtils.convertToXml(result).getBytes()); } @Override public Object doDecodeResponse(InputStream input, JavaType type) throws Exception { return JAXBUtils.convertToJavaBean(input, type); } } ``` 2. Add a configuration file In the META-INF/services/ folder under resources, create a new file xxx.ProduceProcessor (xxx is the package name of the interface), and fill in the content xxx.ProduceAppXmlProcessor (xxx is the package name of the implementation class).","title":"extension"},{"location":"general-development/produceprocess/#rewrite","text":"Developers can rewrite the existing application/json and text/plain implementation logic, or rewrite the self-extended format to rewrite the xml serialization method as an example: 1. Create a class named 'ProduceAppXmlProcessor with the same name to implement the interface ProduceProcessor`. 2. Rewrite the codec logic in the doEncodeResponse and doDecodeResponse methods 3. Change the return value in the getOrder method, which is smaller than the return value of the original method. For example, return -1, the original method return value of application/json and text/plain defaults to 0. 4. In the META-INF/services/ folder under resources, create a new file xxx.ProduceProcessor (xxx is the package name of the interface), and fill in the content xxx.ProduceAppXmlProcessor (xxx is the package name of the implementation class).","title":"Rewrite"},{"location":"general-development/produceprocess/#verification","text":"Service providers provide xml serialization capabilities through producer declarations java @RequestMapping(path = \"/appXml\", method = RequestMethod.POST, produces = MediaType.APPLICATION_XML_VALUE) public JAXBPerson appXml(@RequestBody JAXBPerson person) { return person; } The service consumer indicates the return value xml serialization mode through the request's Accept header. java private void testCodeFirstAppXml(RestTemplate template, String cseUrlPrefix) { JAXBPerson person = new JAXBPerson(\"jake\", 22, \"it\", \"60kg\"); person.setJob(new JAXBJob(\"developer\", \"coding\")); HttpHeaders headers = new HttpHeaders(); headers.add(\"Accept\", MediaType.APPLICATION_XML_VALUE); HttpEntity<JAXBPerson> requestEntity = new HttpEntity<>(person, headers); ResponseEntity<JAXBPerson> resEntity = template.exchange(cseUrlPrefix + \"appXml\", HttpMethod.POST, requestEntity, JAXBPerson.class); TestMgr.check(person, resEntity.getBody()); }","title":"verification"},{"location":"general-development/reactive/","text":"Simple Synchronization Mode Producer: Sample code: @GetMapping(path = \"/hello/{name}\") public String hello(@PathVariable(name = \"name\") String name){ return \"hello \" + name; } The corresponding processing flow is as follows: This is the traditional typical working model. The core idea is not to block network threads, and to put the business in a separate thread (to simplify the expression, only one thread is drawn in the executor) In general, this mode is not a big problem. Nested synchronous call: Not all services are handled simply, you can respond directly, you may need to call other microservices. Sample code: public interface Intf{ String hello(String name); } @GetMapping(path = \"/hello/{name}\") public String hello(@PathVariable(name = \"name\") String name){ return \"from remote: hello \" + intf.hello(name); } The corresponding processing flow is as follows: According to the characteristics of this process, you can see the following results: Because it is a synchronous call, the calling thread of \"Microservice A\" is always in the blocking wait state before \"Other microservices\" is not answered, and does not process any other transactions. When all threads in the Executor are waiting for a remote response, all new requests can only be queued in the Queue and cannot be processed. At this point, the entire system is equivalent to stop working. To increase the processing power, only increase the number of threads in the Executor, and the operating system can not increase the number of threads indefinitely. The benefit of increasing the number of threads is a parabolic model. After a specific critical value, the system handles The ability will drop, and this threshold will not be too big. When the remote synchronization operation is required multiple times in the business logic, the problem will be bigger than before. \"Error\" optimization for nested synchronous calls: For the previous scenario, someone would think that throwing the \"Invoke producer method\" into another thread pool can solve the problem, including the following: In the producer method, mark @Async, which is responsible for throwing the call to the method into other thread pools. Transferring threads through business code inside the producer method Form the following process: According to the characteristics of this process, you can see the following results: \"Invoke producer method\" must be returned immediately, otherwise, the Executor thread will not be released \"Invoke producer method\" must provide a new mechanism to inform the calling process of its return value, not the final return value (currently no such mechanism) Although the Executor thread is released, the Customer Executor is blocked, waiting for the remote response, the blocking state of the entire system has not changed, and there is one more thread switching. The mechanism seems to have the only effect is to release the executor thread, so that the executor thread has the opportunity to process other requests, which is equivalent to the concept of quarantine, the slow processing of the business does not affect other services; but the concept of serviceComb can be directly Supported, you can configure the specified business method to monopolize the new executor, so that the whole process is the same as the \"nested synchronous call\", the process is simpler, and you don't need to do this at the \"Invoke producer method\" level. Pure Reactive Mechanism Sample code: public interface Intf{ CompletableFuture<String> hello(String name); } @GetMapping(path = \"/hello/{name}\") public CompletableFuture<String> hello(@PathVariable(name = \"name\") String name){ CompletableFuture<String> future = new CompletableFuture<>(); intf.hello(name).whenComplete((result, exception) -> { if (exception == null) { future.complete(\"from remote: \" + result); return; } future.completeExceptionally(exception); }); return future; } The corresponding processing flow is as follows: Unlike traditional processes, all functions are executed in the eventloop and no thread switching is performed. After the orange arrow is finished, the occupation of this thread is completed, and it will not block waiting for response. The thread can handle other tasks. After receiving the remote response, the network data drive starts to take the red arrow response process As long as there are tasks, the thread will not stop, the task will be executed all the time, you can make full use of the cpu resources, and will not generate redundant thread switching, to consume the CPU unnecessarily. Because in synchronous mode, a large number of threads are needed to increase the degree of concurrency, and a large number of threads bring additional consumption of thread switching. The test data shows that the reactive mode only needs to consume less than half of the CPU of the synchronous mode. And can reach or exceed the tps of the synchronous mode, and the delay is lower. Hybrid Reactive Mechanism Reactive requires that all logic executed in the eventloop does not allow any blocking actions, including not limited to wait, sleep, large loops, synchronous query DB, and so on. The bottom of serviceComb is based on vertx. The vertx ecosystem has reactive drivers for various rich components such as JDBC, MQ, zooKeeper, etc. Under normal circumstances, it can meet the requirements. However, in some scenarios, there are indeed some synchronization operations that cannot be avoided, such as: Private security hardened redis, only provides synchronous drive More complex business operations ...... At this point, the logic of these synchronizations can be extracted and placed in the thread pool for processing, while other parts still use the reactive process. Some notes about reactive: Producer: * Whether the producer uses reactive and consumer to call, there is no connection * When the operation return value is the CompletableFuture type, the default operation is in reactive mode. If you need to force this operation to work in thread pool mode, you need to configure it in microservice.yaml explicitly. If an operation, its schemaId is sid, operationId For asyncQuery, you need to do the following: servicecomb: executors: Provider: sid.asyncQuery: cse.executor.groupThreadPool The cse.executor.groupThreadPool here is the default thread pool built into serviceComb, which can be arbitrarily specified by the user as its custom thread pool. Consumer: * Whether the consumer uses reactive and producer how to implement, there is no connection * Currently only supports transparent RPC mode, using JDK native CompletableFuture to carry this function completableFuture's when, then, etc. can be used directly However, the async series of completableFuture is another thread pool to perform functions. It is not recommended. Support for RxJava Observable will be added later. Support for AsyncRestTemplate will be added later.","title":"Reactive Programing"},{"location":"general-development/reactive/#simple-synchronization-mode-producer","text":"Sample code: @GetMapping(path = \"/hello/{name}\") public String hello(@PathVariable(name = \"name\") String name){ return \"hello \" + name; } The corresponding processing flow is as follows: This is the traditional typical working model. The core idea is not to block network threads, and to put the business in a separate thread (to simplify the expression, only one thread is drawn in the executor) In general, this mode is not a big problem.","title":"Simple Synchronization Mode Producer:"},{"location":"general-development/reactive/#nested-synchronous-call","text":"Not all services are handled simply, you can respond directly, you may need to call other microservices. Sample code: public interface Intf{ String hello(String name); } @GetMapping(path = \"/hello/{name}\") public String hello(@PathVariable(name = \"name\") String name){ return \"from remote: hello \" + intf.hello(name); } The corresponding processing flow is as follows: According to the characteristics of this process, you can see the following results: Because it is a synchronous call, the calling thread of \"Microservice A\" is always in the blocking wait state before \"Other microservices\" is not answered, and does not process any other transactions. When all threads in the Executor are waiting for a remote response, all new requests can only be queued in the Queue and cannot be processed. At this point, the entire system is equivalent to stop working. To increase the processing power, only increase the number of threads in the Executor, and the operating system can not increase the number of threads indefinitely. The benefit of increasing the number of threads is a parabolic model. After a specific critical value, the system handles The ability will drop, and this threshold will not be too big. When the remote synchronization operation is required multiple times in the business logic, the problem will be bigger than before.","title":"Nested synchronous call:"},{"location":"general-development/reactive/#error-optimization-for-nested-synchronous-calls","text":"For the previous scenario, someone would think that throwing the \"Invoke producer method\" into another thread pool can solve the problem, including the following: In the producer method, mark @Async, which is responsible for throwing the call to the method into other thread pools. Transferring threads through business code inside the producer method Form the following process: According to the characteristics of this process, you can see the following results: \"Invoke producer method\" must be returned immediately, otherwise, the Executor thread will not be released \"Invoke producer method\" must provide a new mechanism to inform the calling process of its return value, not the final return value (currently no such mechanism) Although the Executor thread is released, the Customer Executor is blocked, waiting for the remote response, the blocking state of the entire system has not changed, and there is one more thread switching. The mechanism seems to have the only effect is to release the executor thread, so that the executor thread has the opportunity to process other requests, which is equivalent to the concept of quarantine, the slow processing of the business does not affect other services; but the concept of serviceComb can be directly Supported, you can configure the specified business method to monopolize the new executor, so that the whole process is the same as the \"nested synchronous call\", the process is simpler, and you don't need to do this at the \"Invoke producer method\" level.","title":"\"Error\" optimization for nested synchronous calls:"},{"location":"general-development/reactive/#pure-reactive-mechanism","text":"Sample code: public interface Intf{ CompletableFuture<String> hello(String name); } @GetMapping(path = \"/hello/{name}\") public CompletableFuture<String> hello(@PathVariable(name = \"name\") String name){ CompletableFuture<String> future = new CompletableFuture<>(); intf.hello(name).whenComplete((result, exception) -> { if (exception == null) { future.complete(\"from remote: \" + result); return; } future.completeExceptionally(exception); }); return future; } The corresponding processing flow is as follows: Unlike traditional processes, all functions are executed in the eventloop and no thread switching is performed. After the orange arrow is finished, the occupation of this thread is completed, and it will not block waiting for response. The thread can handle other tasks. After receiving the remote response, the network data drive starts to take the red arrow response process As long as there are tasks, the thread will not stop, the task will be executed all the time, you can make full use of the cpu resources, and will not generate redundant thread switching, to consume the CPU unnecessarily. Because in synchronous mode, a large number of threads are needed to increase the degree of concurrency, and a large number of threads bring additional consumption of thread switching. The test data shows that the reactive mode only needs to consume less than half of the CPU of the synchronous mode. And can reach or exceed the tps of the synchronous mode, and the delay is lower.","title":"Pure Reactive Mechanism"},{"location":"general-development/reactive/#hybrid-reactive-mechanism","text":"Reactive requires that all logic executed in the eventloop does not allow any blocking actions, including not limited to wait, sleep, large loops, synchronous query DB, and so on. The bottom of serviceComb is based on vertx. The vertx ecosystem has reactive drivers for various rich components such as JDBC, MQ, zooKeeper, etc. Under normal circumstances, it can meet the requirements. However, in some scenarios, there are indeed some synchronization operations that cannot be avoided, such as: Private security hardened redis, only provides synchronous drive More complex business operations ...... At this point, the logic of these synchronizations can be extracted and placed in the thread pool for processing, while other parts still use the reactive process.","title":"Hybrid Reactive Mechanism"},{"location":"general-development/reactive/#some-notes-about-reactive","text":"Producer: * Whether the producer uses reactive and consumer to call, there is no connection * When the operation return value is the CompletableFuture type, the default operation is in reactive mode. If you need to force this operation to work in thread pool mode, you need to configure it in microservice.yaml explicitly. If an operation, its schemaId is sid, operationId For asyncQuery, you need to do the following: servicecomb: executors: Provider: sid.asyncQuery: cse.executor.groupThreadPool The cse.executor.groupThreadPool here is the default thread pool built into serviceComb, which can be arbitrarily specified by the user as its custom thread pool. Consumer: * Whether the consumer uses reactive and producer how to implement, there is no connection * Currently only supports transparent RPC mode, using JDK native CompletableFuture to carry this function completableFuture's when, then, etc. can be used directly However, the async series of completableFuture is another thread pool to perform functions. It is not recommended. Support for RxJava Observable will be added later. Support for AsyncRestTemplate will be added later.","title":"Some notes about reactive:"},{"location":"general-development/report-framework-version/","text":"Concept Description To facilitate the management, using ServiceComb for development, the currently used ServiceComb version number will be reported to the service center, and the version number of other frameworks will be reported when other frameworks integrate ServiceComb. Sample Code Step 1 First, implement the Versions interface of the open source framework ServiceComb, implement the loadVersion method under the interface, and return the version name and version number as key-value pairs. public class MyVersion implements Versions{ @override public Map<String, String> loadVersion() { Map<String, String> map = new HashMap<>(); map.put(\"My\", this.getClass().getPackage().getImplementationVersion()); return map; } } Step 2 To use the SPI mechanism to make the returned object read by ServiceComb, you need to add the services folder in META-INF and add a file to it, with the name of the interface xxxVersions\\ (with package name). Take the concrete implementation class xxxCseVersion\\ (with package name) as the content When the service is registered to the ServiceCenter, it will carry all version number information. { \"serviceId\": \"xxx\", \"appId\": \"xxx\", \"registerBy\": \"SDK\", \"framework\": { \"name\": \"servicecomb-java-chassis\", \"version\": \"My:x.x.x;ServiceComb:x.x.x\" } } Remarks The reported version number can be customized, or it can be read from the MANIFEST.MF of the pom or jar package. If you use .class.getPackage().getImplementationVersion() to get the version number from MANIFEST.MF, you need to Set the maven-jar-plugin archive elements addDefaultImplementationEntries and addDefaultSpecificationEntries to true in the pom file. <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifest> <addDefaultImplementationEntries>true</addDefaultImplementationEntries> <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries> </manifest> </archive> </configuration> </plugin>","title":"Report framework version"},{"location":"general-development/report-framework-version/#concept-description","text":"To facilitate the management, using ServiceComb for development, the currently used ServiceComb version number will be reported to the service center, and the version number of other frameworks will be reported when other frameworks integrate ServiceComb.","title":"Concept Description"},{"location":"general-development/report-framework-version/#sample-code","text":"Step 1 First, implement the Versions interface of the open source framework ServiceComb, implement the loadVersion method under the interface, and return the version name and version number as key-value pairs. public class MyVersion implements Versions{ @override public Map<String, String> loadVersion() { Map<String, String> map = new HashMap<>(); map.put(\"My\", this.getClass().getPackage().getImplementationVersion()); return map; } } Step 2 To use the SPI mechanism to make the returned object read by ServiceComb, you need to add the services folder in META-INF and add a file to it, with the name of the interface xxxVersions\\ (with package name). Take the concrete implementation class xxxCseVersion\\ (with package name) as the content When the service is registered to the ServiceCenter, it will carry all version number information. { \"serviceId\": \"xxx\", \"appId\": \"xxx\", \"registerBy\": \"SDK\", \"framework\": { \"name\": \"servicecomb-java-chassis\", \"version\": \"My:x.x.x;ServiceComb:x.x.x\" } } Remarks The reported version number can be customized, or it can be read from the MANIFEST.MF of the pom or jar package. If you use .class.getPackage().getImplementationVersion() to get the version number from MANIFEST.MF, you need to Set the maven-jar-plugin archive elements addDefaultImplementationEntries and addDefaultSpecificationEntries to true in the pom file. <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifest> <addDefaultImplementationEntries>true</addDefaultImplementationEntries> <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries> </manifest> </archive> </configuration> </plugin>","title":"Sample Code"},{"location":"general-development/secret-field/","text":"Scenario Due to the non-security of the HTTP protocol, data transmitted over the network can be easily monitored by various packet capture tools. In practical applications, services have high security requirements for sensitive data transmitted between applications or services. Such data requires special encryption protection (different services have different algorithm requirements) so that even if the content is intercepted, it can protect. Sensitive data is not easily obtained. Solution The communication between services leaves unserialized and deserialized. For the above scenario, the @JsonSerialize and @JsonDeserialize annotation functions provided by the jackson class library are used to customize the serialization and deserialization methods for sensitive data, and in a customized method. Implement encryption and decryption functions. Annotation descriptive reference: Find the corresponding version of Javadocs in [https://github.com/FasterXML/jackson-databind/wiki] (https://github.com/FasterXML/jackson-databind/wiki) example Use the specific serialization and deserialization methods for annotations by setting the name property in the Person object. Note: This shows how to use it, not related to encryption and decryption. public class Person { private int usrId; // Specify data name using a specific serialization and deserialization method @JsonSerialize(using = SecretSerialize.class) @JsonDeserialize(using = SecretDeserialize.class) private String name; public int getUsrId() { return usrId; } public void setUsrId(int usrId) { this.usrId = usrId; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return \"Person{\" + \"usrId=\" + usrId + \", name='\" + name + '\\'' + '}'; } } Define the SecretSerialize class and the SecretDeserialize class and override their methods public class SecretSerialize extends JsonSerializer<String> { // Rewrite the serialization method of a name, where you can implement custom encryption or decryption or other operations @Override public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException { // Add 4 specific characters after the data name value = value + \" &#@\"; // Perform serialization operations gen.writeString(value); } } public class SecretDeserialize extends JsonDeserializer<String> { // Rewrite the deserialization method of a name, match the serialize serialization method, get the real data according to the rules customized by the user @Override public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { // Get the deserialized data, remove 4 specific characters, get the real name String value = p.getValueAsString(); value = value.substring(0, value.length() - 4); return value; } }","title":"Customized serialization and deserialization"},{"location":"general-development/secret-field/#scenario","text":"Due to the non-security of the HTTP protocol, data transmitted over the network can be easily monitored by various packet capture tools. In practical applications, services have high security requirements for sensitive data transmitted between applications or services. Such data requires special encryption protection (different services have different algorithm requirements) so that even if the content is intercepted, it can protect. Sensitive data is not easily obtained.","title":"Scenario"},{"location":"general-development/secret-field/#solution","text":"The communication between services leaves unserialized and deserialized. For the above scenario, the @JsonSerialize and @JsonDeserialize annotation functions provided by the jackson class library are used to customize the serialization and deserialization methods for sensitive data, and in a customized method. Implement encryption and decryption functions. Annotation descriptive reference: Find the corresponding version of Javadocs in [https://github.com/FasterXML/jackson-databind/wiki] (https://github.com/FasterXML/jackson-databind/wiki)","title":"Solution"},{"location":"general-development/secret-field/#example","text":"Use the specific serialization and deserialization methods for annotations by setting the name property in the Person object. Note: This shows how to use it, not related to encryption and decryption. public class Person { private int usrId; // Specify data name using a specific serialization and deserialization method @JsonSerialize(using = SecretSerialize.class) @JsonDeserialize(using = SecretDeserialize.class) private String name; public int getUsrId() { return usrId; } public void setUsrId(int usrId) { this.usrId = usrId; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return \"Person{\" + \"usrId=\" + usrId + \", name='\" + name + '\\'' + '}'; } } Define the SecretSerialize class and the SecretDeserialize class and override their methods public class SecretSerialize extends JsonSerializer<String> { // Rewrite the serialization method of a name, where you can implement custom encryption or decryption or other operations @Override public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException { // Add 4 specific characters after the data name value = value + \" &#@\"; // Perform serialization operations gen.writeString(value); } } public class SecretDeserialize extends JsonDeserializer<String> { // Rewrite the deserialization method of a name, match the serialize serialization method, get the real data according to the rules customized by the user @Override public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { // Get the deserialized data, remove 4 specific characters, get the real name String value = p.getValueAsString(); value = value.substring(0, value.length() - 4); return value; } }","title":"example"},{"location":"general-development/service-information-printer/","text":"Printing Service Information Conception Illustration In order make it easier and faster for users to gather the service information, those data are collected and printed on the log. effect How the printing looks like: No matter the initialization of the service succeeded or not, the service information will be printed at the end of the log, users can search by \"Service Information is shown below\" to locate it 2019-08-21 16:37:14,859 [INFO] Service information is shown below: service center: [http://127.0.0.1:30100] config center: [http://127.0.0.1:30113] AppID: Restful-Service-HelloWorld ServiceName: restful_provider Version: 0.0.1 Environment: production ServiceID: a3344e9ad4557f883b36d7f53e33306fbc0a54ad InstanceID; e0765a8ec3ee11e9910d0255ac105780 org.apache.servicecomb.core.SCBEngine$1.afterRegistryInstance(SCBEngine.java:243) extension related interfaces and classes interface: BootUpInformationCollector collect(): return a string\uff0cwhich is the information that should be printed on the log getOrder():return the priority of the implementation classes of BootUpInformationCollector, the smaller the number, the higher the priority. how users implement extension to make extension of the printing service, user need to: 1. Create new classes that implements Interface BootUpInformationCollector, and set the appropriate order. 2. Create SPI file. example Create a new implementation class HelloCollector. public class HelloCollector implements BootUpInformationCollector { @Override public String collect() { return \"Hello!\"; } @Override public int getOrder() { return 5; } } because the order of this class is 5, it will be printed between the address information(order 0) and service information(order 200) 2. Create SPI file create new SPI file under directory resources/META-INF/services name of the file: org.apache.servicecomb.core.bootup.BootUpInformationCollector content: the class name of HelloCollector 3. printing effect 2019-08-21 16:37:14,859 [INFO] Service information is shown below: service center: [http://127.0.0.1:30100] config center: [http://127.0.0.1:30113] Hello! AppID: Restful-Service-HelloWorld ServiceName: restful_provider Version: 0.0.1 Environment: production ServiceID: a3344e9ad4557f883b36d7f53e33306fbc0a54ad InstanceID; e0765a8ec3ee11e9910d0255ac105780 org.apache.servicecomb.core.SCBEngine$1.afterRegistryInstance(SCBEngine.java:243)","title":"Printing Service Information"},{"location":"general-development/service-information-printer/#printing-service-information","text":"","title":"Printing Service Information"},{"location":"general-development/service-information-printer/#conception-illustration","text":"In order make it easier and faster for users to gather the service information, those data are collected and printed on the log.","title":"Conception Illustration"},{"location":"general-development/service-information-printer/#effect","text":"How the printing looks like: No matter the initialization of the service succeeded or not, the service information will be printed at the end of the log, users can search by \"Service Information is shown below\" to locate it 2019-08-21 16:37:14,859 [INFO] Service information is shown below: service center: [http://127.0.0.1:30100] config center: [http://127.0.0.1:30113] AppID: Restful-Service-HelloWorld ServiceName: restful_provider Version: 0.0.1 Environment: production ServiceID: a3344e9ad4557f883b36d7f53e33306fbc0a54ad InstanceID; e0765a8ec3ee11e9910d0255ac105780 org.apache.servicecomb.core.SCBEngine$1.afterRegistryInstance(SCBEngine.java:243)","title":"effect"},{"location":"general-development/service-information-printer/#extension","text":"","title":"extension"},{"location":"general-development/service-information-printer/#related-interfaces-and-classes","text":"interface: BootUpInformationCollector collect(): return a string\uff0cwhich is the information that should be printed on the log getOrder():return the priority of the implementation classes of BootUpInformationCollector, the smaller the number, the higher the priority.","title":"related interfaces and classes"},{"location":"general-development/service-information-printer/#how-users-implement-extension","text":"to make extension of the printing service, user need to: 1. Create new classes that implements Interface BootUpInformationCollector, and set the appropriate order. 2. Create SPI file.","title":"how users implement extension"},{"location":"general-development/service-information-printer/#example","text":"Create a new implementation class HelloCollector. public class HelloCollector implements BootUpInformationCollector { @Override public String collect() { return \"Hello!\"; } @Override public int getOrder() { return 5; } } because the order of this class is 5, it will be printed between the address information(order 0) and service information(order 200) 2. Create SPI file create new SPI file under directory resources/META-INF/services name of the file: org.apache.servicecomb.core.bootup.BootUpInformationCollector content: the class name of HelloCollector 3. printing effect 2019-08-21 16:37:14,859 [INFO] Service information is shown below: service center: [http://127.0.0.1:30100] config center: [http://127.0.0.1:30113] Hello! AppID: Restful-Service-HelloWorld ServiceName: restful_provider Version: 0.0.1 Environment: production ServiceID: a3344e9ad4557f883b36d7f53e33306fbc0a54ad InstanceID; e0765a8ec3ee11e9910d0255ac105780 org.apache.servicecomb.core.SCBEngine$1.afterRegistryInstance(SCBEngine.java:243)","title":"example"},{"location":"general-development/shutdown/","text":"Shutdown gracefully ServiceComb achieve graceful shutdown through JDK's ShutdownHook. Scenes Graceful shutdown can solve the following scenes: * KILL PID * Application automatically exits unexpectedly\uff08System.exit(n)\uff09 Graceful shutdown can't solve the following scenes: * KILL -9 PID or taskkill /f /pid Effect When triggering graceful shutdown: * Provider: * Mark the current service status as STOPPING, do not accept new client requests, the new request will report error directly on the client, and the client cooperates with the retry mechanism to retry other instances; * Wait for the currently running thread to finish executing. If the provider side has set timeout, will be forced to close after timeout; * consumer: * Mark the current service state as STOPPING, do not send a new call request; * Waiting for the response of the currently sent request, if it exceeds the timeout period for the client to receive the response (default 30 seconds), it is forcibly closed; Principle When an graceful shutdown is triggered, the following steps are performed in sequence: 1. Send a BEFORE_CLOSE event to all listeners, and notify the listener to handle the corresponding event; 2. Mark the current service status as STOPPING; 3. Log out the current microservice instance from the service center and close the vertx corresponding registry; 4. Waiting for all currently existing invocation calls to complete; 5. Close the vertx corresponding to config-center and transport; 6. Send an AFTER_CLOSE event to all listeners, and notify the listener to handle the corresponding event; 7. Mark the current service status as DOWN; graceful shutdown ends;","title":"Shutdown gracefully"},{"location":"general-development/shutdown/#shutdown-gracefully","text":"ServiceComb achieve graceful shutdown through JDK's ShutdownHook.","title":"Shutdown gracefully"},{"location":"general-development/shutdown/#scenes","text":"Graceful shutdown can solve the following scenes: * KILL PID * Application automatically exits unexpectedly\uff08System.exit(n)\uff09 Graceful shutdown can't solve the following scenes: * KILL -9 PID or taskkill /f /pid","title":"Scenes"},{"location":"general-development/shutdown/#effect","text":"When triggering graceful shutdown: * Provider: * Mark the current service status as STOPPING, do not accept new client requests, the new request will report error directly on the client, and the client cooperates with the retry mechanism to retry other instances; * Wait for the currently running thread to finish executing. If the provider side has set timeout, will be forced to close after timeout; * consumer: * Mark the current service state as STOPPING, do not send a new call request; * Waiting for the response of the currently sent request, if it exceeds the timeout period for the client to receive the response (default 30 seconds), it is forcibly closed;","title":"Effect"},{"location":"general-development/shutdown/#principle","text":"When an graceful shutdown is triggered, the following steps are performed in sequence: 1. Send a BEFORE_CLOSE event to all listeners, and notify the listener to handle the corresponding event; 2. Mark the current service status as STOPPING; 3. Log out the current microservice instance from the service center and close the vertx corresponding registry; 4. Waiting for all currently existing invocation calls to complete; 5. Close the vertx corresponding to config-center and transport; 6. Send an AFTER_CLOSE event to all listeners, and notify the listener to handle the corresponding event; 7. Mark the current service status as DOWN; graceful shutdown ends;","title":"Principle"},{"location":"general-development/thread-model/","text":"Threading model Threading model in synchronous mode Threading model in reactive mode Thread related configuration\uff1a REST over Vertx Highway Server business thread pool in synchronous mode","title":"Thread Model"},{"location":"general-development/thread-model/#threading-model","text":"","title":"Threading model"},{"location":"general-development/thread-model/#threading-model-in-synchronous-mode","text":"","title":"Threading model in synchronous mode"},{"location":"general-development/thread-model/#threading-model-in-reactive-mode","text":"Thread related configuration\uff1a REST over Vertx Highway Server business thread pool in synchronous mode","title":"Threading model in reactive mode"},{"location":"general-development/types/","text":"","title":"Types"},{"location":"general-development/visit-sc/","text":"Concept Description The system realizes the discovery between services through the service center . During the service startup process, the service center is registered. When calling other services, the service center will query the instance information of other services, such as the access address, the protocol used, and other parameters. The service center supports the use of PULL and PUSH modes to notify instance changes. Developers can configure service center clusters addresses, connection parameters, heartbeat management and so on. Configuration instructions Table 1-1 Accessing Common Configuration Items in the Configuration Center Configuration Item Reference / Default Value Range Required Meaning servicecomb.service.registry.address http://127.0.0.1:30100 Yes Service center address information, you can configure multiple, separated by commas. servicecomb.service.registry.instance. Watch true No Whether to monitor instance changes in PUSH mode. When it is false, it means using PULL mode. servicecomb.service.registry. Autodiscovery false No Whether to automatically discover the address of the service center. This configuration is enabled when a partial address needs to be configured, and other addresses are discovered by the configured service center instance. servicecomb.service.registry.instance.healthCheck.interval 30 No Heartbeat interval. servicecomb.service.registry.instance.healthCheck.times 3 No Number of allowed heartbeat failures. If there is (times + 1) continuous heartbeat failures, this instance will be automatically logged off by service-center, i.e. interval * (times + 1) determines when the instance is automatically logged off. If the service center waits for such a long time and does not receive a heartbeat, the instance will be logged off. servicecomb.service.registry.instance.empty.protection true No When service center gives empty server list, will not remove local address cache when true. servicecomb.service.registry.client.timeout.connection 30000 Connection timeout in milliseconds servicecomb.service.registry.client.timeout.request 30000 Request timeout in milliseconds servicecomb.service.registry.client.timeout.idle 60 Connection idle timeout in milliseconds servicecomb.service.registry.client.timeout.heartbeat 3000 Heartbeat request timeout in milliseconds servicecomb.service.registry.client.instances 1 No the account of verticle instances that Service Registry Client had been deployed servicecomb.service.registry.client.eventLoopPoolSize 4 No the size of Service Registry client Event Loop pool servicecomb.service.registry.client.workerPoolSize 4 No the size of Service Registry client worker pool","title":"Access Service Center"},{"location":"general-development/visit-sc/#concept-description","text":"The system realizes the discovery between services through the service center . During the service startup process, the service center is registered. When calling other services, the service center will query the instance information of other services, such as the access address, the protocol used, and other parameters. The service center supports the use of PULL and PUSH modes to notify instance changes. Developers can configure service center clusters addresses, connection parameters, heartbeat management and so on.","title":"Concept Description"},{"location":"general-development/visit-sc/#configuration-instructions","text":"","title":"Configuration instructions"},{"location":"general-development/visit-sc/#table-1-1-accessing-common-configuration-items-in-the-configuration-center","text":"Configuration Item Reference / Default Value Range Required Meaning servicecomb.service.registry.address http://127.0.0.1:30100 Yes Service center address information, you can configure multiple, separated by commas. servicecomb.service.registry.instance. Watch true No Whether to monitor instance changes in PUSH mode. When it is false, it means using PULL mode. servicecomb.service.registry. Autodiscovery false No Whether to automatically discover the address of the service center. This configuration is enabled when a partial address needs to be configured, and other addresses are discovered by the configured service center instance. servicecomb.service.registry.instance.healthCheck.interval 30 No Heartbeat interval. servicecomb.service.registry.instance.healthCheck.times 3 No Number of allowed heartbeat failures. If there is (times + 1) continuous heartbeat failures, this instance will be automatically logged off by service-center, i.e. interval * (times + 1) determines when the instance is automatically logged off. If the service center waits for such a long time and does not receive a heartbeat, the instance will be logged off. servicecomb.service.registry.instance.empty.protection true No When service center gives empty server list, will not remove local address cache when true. servicecomb.service.registry.client.timeout.connection 30000 Connection timeout in milliseconds servicecomb.service.registry.client.timeout.request 30000 Request timeout in milliseconds servicecomb.service.registry.client.timeout.idle 60 Connection idle timeout in milliseconds servicecomb.service.registry.client.timeout.heartbeat 3000 Heartbeat request timeout in milliseconds servicecomb.service.registry.client.instances 1 No the account of verticle instances that Service Registry Client had been deployed servicecomb.service.registry.client.eventLoopPoolSize 4 No the size of Service Registry client Event Loop pool servicecomb.service.registry.client.workerPoolSize 4 No the size of Service Registry client worker pool","title":"Table 1-1 Accessing Common Configuration Items in the Configuration Center"},{"location":"packaging/standalone/","text":"Concept Description A Standalone container that loads Spring with a simple Main, because the service usually does not require the properties of a Web container such as Tomcat/JBoss, and there is no need to use the Web container to load the service. The microframework provides a standalone deployment run mode. The service container is just a simple Main method and loads a simple Spring container to expose the service. Operation steps Step 1 Write the Main function, initialize the log and load the service configuration as follows: import org.apache.servicecomb.foundation.common.utils.BeanUtils; import org.apache.servicecomb.foundation.common.utils.Log4jUtils; public class MainServer { public static void main(String[] args) throws Exception { \u3000Log4jUtils.init(); # Log initialization \u3000BeanUtils.init(); # Spring bean initialization } } Step 2 Run the MainServer to start the microservice process and expose the service. Notes If you are using the rest network channel, you need to change the transport in the pom to use the cse-transport-rest-vertx package.","title":"Standalone mode"},{"location":"packaging/standalone/#concept-description","text":"A Standalone container that loads Spring with a simple Main, because the service usually does not require the properties of a Web container such as Tomcat/JBoss, and there is no need to use the Web container to load the service. The microframework provides a standalone deployment run mode. The service container is just a simple Main method and loads a simple Spring container to expose the service.","title":"Concept Description"},{"location":"packaging/standalone/#operation-steps","text":"Step 1 Write the Main function, initialize the log and load the service configuration as follows: import org.apache.servicecomb.foundation.common.utils.BeanUtils; import org.apache.servicecomb.foundation.common.utils.Log4jUtils; public class MainServer { public static void main(String[] args) throws Exception { \u3000Log4jUtils.init(); # Log initialization \u3000BeanUtils.init(); # Spring bean initialization } } Step 2 Run the MainServer to start the microservice process and expose the service.","title":"Operation steps"},{"location":"packaging/standalone/#notes","text":"If you are using the rest network channel, you need to change the transport in the pom to use the cse-transport-rest-vertx package.","title":"Notes"},{"location":"packaging/web-container/","text":"Concept Description If you need to load the microservice into the web container to start the runtime, you need to create a new servlet project wrapper, the servlet project, you just need to write few lines of code Development example Refer to the \"Development Service Provider\" -> \"Communication Protocol\" -> \"REST over Servlet\" chapter. Notes Restful calls should be isolated from other static resource calls (such as html, js, etc.) in the web container, so there should be a layer of keywords in the post after webroot, such as the example in web.xml above (/test/rest) In the rest. Take tomcat as an example. By default, each war package has a different webroot. This webroot needs to be a basePath prefix. For example, if webroot is testing, all the contracts of the microservice must start with /test. When the microservice is loaded in the web container and directly uses the http and https ports opened by the web container, it is necessary to satisfy the rules of the web container because it is the communication channel of the web container used.","title":"WEB container mode"},{"location":"packaging/web-container/#concept-description","text":"If you need to load the microservice into the web container to start the runtime, you need to create a new servlet project wrapper, the servlet project, you just need to write few lines of code","title":"Concept Description"},{"location":"packaging/web-container/#development-example","text":"Refer to the \"Development Service Provider\" -> \"Communication Protocol\" -> \"REST over Servlet\" chapter.","title":"Development example"},{"location":"packaging/web-container/#notes","text":"Restful calls should be isolated from other static resource calls (such as html, js, etc.) in the web container, so there should be a layer of keywords in the post after webroot, such as the example in web.xml above (/test/rest) In the rest. Take tomcat as an example. By default, each war package has a different webroot. This webroot needs to be a basePath prefix. For example, if webroot is testing, all the contracts of the microservice must start with /test. When the microservice is loaded in the web container and directly uses the http and https ports opened by the web container, it is necessary to satisfy the rules of the web container because it is the communication channel of the web container used.","title":"Notes"},{"location":"packaging/web-container/#_1","text":"","title":""},{"location":"question-and-answer/faq/","text":"Q: What is the relationship between ServiceComb and SpringCloud, and what is ServiceComb specific application scenarios? A: ServiceComb is a set of microservice development frameworks based on large-scale IT system practices. It encapsulates a set of microservices running models based on best practices in development. These capabilities are completely transparent to users,it can be integrated and adjusted by configuration. In the operation and maintenance phase, microservices operation and maintenance have been fully considered, providing rich monitoring indicators and dynamic governance capabilities. B: ServiceComb's capabilities can be used as a separate development framework, in a scenario that requires a lightweight microservice solution, or on SpringCloud, working with other components provided by SpringCloud, in heavyweight The scene together with SpringCloud produces a '1+1>2' effect. Q: Do we have a problem with IntelliJ's free version? A: No problem, use IntelliJ development, refer to [Setup Developer Environment] (/cn/developers/setup-develop-environment/) for the corresponding environment configuration. Q: What need to be cautious when using Java-Chassis? A: There are a few restrictions when using Java-Chassis: * Before version 0.3.0-SNAPSHOT, it does not support annotations like @GetMapping . * When using the same HTTP request method, e.g. GET, the method name need to be unique as it will become operation ID when swagger generates contracts. * Class and method name need to be public. Q: Contract generation will report error: 'Caused by: java.lang.Error: OperationId must be unique', does not support function overriding? A: We support function overriding, plus the @ApiOperation tag. There are examples in demo-pojo. Each interface must have a unique operation id. Q: When using the spring-boot-starter-provider dependency, property like spring.main.web-environment not working in application.yml file. A: When you need both the starter provider dependency and the servlet, you need to declare spring.main.web-environment in application.properties file or declare it in application.yml file and create an empty application.properties file. Q: What's the dependency differences between gateway and other microservices? xml <groupId>org.apache.servicecomb</groupId> <artifactId>spring-boot-starter-provider</artifactId> A: Gateway depends on not only the spring-boot-starter-provider , but also the spring-boot-starter-discovery . This can refer to the manger implementation of LinuxCon-Beijing-Workshop . Q: Do gateway need to configure assembly like the other microservices? Is /maven/gateway the default path of the docker maven plugin? A: Yes. Docker maven plugin relies on the assembly files to generate docker image. /maven is the default path of docker maven plugin and /gateway is the path defined in the assembly file. Q: Are there any restrictions of the return type of our API? Should it be the type of ResponseEntity? A: No, examples can refer to the implementation of integration-test in java-chassis. Q: After the microservice is started, the interface cannot be called correctly, or is there no error returned? A: Please check that the calling path is exactly the same as the path published in the Producer implementation code. The boot log on the Producer side can see the output of the map path, for example: [INFO] Swagger mapped \"{[/hello/], method=[GET], produces=[application/json]}\" For different programming styles (models) to implement Producer documentation and notes, please see: Jaxrs SpringMVC Pojo Spring Boot . 10. Q: The port number under the microservice.yaml configuration file has been modified via eclipse. After starting the program, the port number does not work? A: You need to import the sample project alone. If you import the entire ServiceComb-Java-Chassis project, the IDE will not compile the sample because the sample directory is not in the ServiceComb-Java-Chassis module. There is no error message under eclipse. Prompt message. Therefore, eclipse starts the demo of the sample and will find that the modified port does not work. 12. Q: How do I customize the HTTP status code in the REST interface for a Java method? A: For normal return values, you can do this with SwaggerAnnotation, for example: java @ApiResponse(code = 300, response = String.class, message = \"\") public int test(int x) { return 100; } For the return value of the exception, you can do this by throwing a custom InvocationException, for example: ```java public String testException(int code) { String strCode = String.valueOf(code); switch (code) { case 200: return strCode; case 456: throw new InvocationException(code, strCode, strCode + \" error\"); case 556: throw new InvocationException(code, strCode, Arrays.asList(strCode + \" error\")); case 557: throw new InvocationException(code, strCode, Arrays.asList(Arrays.asList(strCode + \" error\"))); default: break; } return \"not expected\"; } ``` Q: How to customize the log configuration of your own microservice? A: ServiceComb does not bind the logger, just uses slf4j, users can freely choose log4j/log4j2/logback and so on. ServiceComb provides a log4j extension that supports incremental configuration of log4j's properties files on a standard log4j basis. * By default, the configuration file is loaded by the rule: \"classpath*:config/log4j.properties\" * Actually search all the config/log4j.properties and config/log4j.*.properties in the classpath, and cut out the \\* from the searched file to perform alpha. Sort, then load in order, and the final synthesized file is used as the log4j configuration file. * If you want to use ServiceComb's log4j extension, you need to call Log4jUtils.init, otherwise it will be used according to the rules of the standard logger. Q: When the service is configured with multiple transports, how do you choose which transport to use at runtime? A: * ServiceComb's consumer, transport, handler, and producer are decoupled, and each function works together through contract definitions, namely: Consumer use transparent rpc, or springmvc development and use of highway, or RESTful transmission on the network does not matter with the producer is to use transparent rpc, or jaxrs, or springmvc development, there is no relationship between the receiver is not perceived, business development methods and transmission methods * Consumer access to the producer, at the runtime's transport selection, the general rule is: The consumer's transport and the producer's endpoint take the intersection. If there are multiple transports after the intersection, they are used in turn. Decomposed, there are the following scenarios: * When a microservice producer opens both the highway and the RESTful endpoint * Only the highway transport jar is deployed in the consumer process, only the producer's highway endpoint is accessed. * Only the RESTful transport jar is deployed in the consumer process, only the RESTful endpoint of the producer is accessed. * In the consumer process, both the highway and RESTful transport jars are deployed, and the producer's highway and RESTful endpoints are accessed in turn. If, at this time, the consumer wants to use a transport to access the producer, it can be configured in the microservice.yaml of the consumer process, specifying the name of the transport: yaml Servicecomb: References: <service_name>: Transport: highway * When a microservice producer only opens the endpoint of the highway * The consumer process only deploys the highway transport jar, then the highway access is normally used. *The consumer process only deploys RESTful transport jars and cannot be accessed * The consumer process deploys both the highway and the RESTful transport jar, and the highway access is normally used. * When a microservice producer only opens RESTful endpoints *The consumer process only deploys the highway transport jar and cannot access it. * The consumer process only deploys RESTful transport jars, which normally uses RESTful access. * The consumer process deploys both the highway and the RESTful transport jar, and the RESTful access is normally used. Q: The swagger body parameter type is incorrectly defined, causing the content registered in the service center to have no type information Symptom: Define the following interface, put the parameters into the body to pass yaml /testInherate: Post: operationId: \"testInherate\" Parameters: - in: \"body\" Name: \"xxxxx\" Required: false Type: string Responses: 200: Description: \"response of 200\" Schema: $ref: \"#/definitions/ResponseImpl\" Define the interface in the above way. After the service is registered, the interface type: string that is queried from the service center is lost and becomes: yaml /testInherate: Post: operationId: \"testInherate\" Parameters: - in: \"body\" Name: \"xxxxx\" Required: false Responses: 200: Description: \"response of 200\" Schema: $ref: \"#/definitions/ResponseImpl\" If the client does not place a swagger, the following exception is also reported: text Caused by: java.lang.ClassFormatError: Method \"testInherate\" in class ? has illegal signature \" A: When defining the type of the body parameter, you need to use the schema. You cannot use type directly. yaml /testInherate: Post: operationId: \"testInherate\" Parameters: - in: \"body\" Name: \"request\" Required: false Schema: Type: string Responses: 200: Description: \"response of 200\" Schema: $ref: \"#/definitions/ResponseImpl\" Q: Does the ServiceComb microservices framework service innovate via long connection? A: http request via a long connection (with a timeout), and the highway mode also via a long connection (all the time). Q: Is the service disconnected service center registration information automatically deleted? A: The service center heartbeat detects that the service instance is unavailable, only the service instance information is removed, and the static data of the service is not removed. Q: How to implement service registration if you use the tomcat method to integrate the ServiceComb microservices framework A: If you use the ServiceComb sdk servlet method (using the transport-rest-servlet dependency) to deploy to the tomcat as a war package, you need to ensure that the rest port configuration in the service description file (microservice.yaml) is consistent with the external container to implement the service. Register correctly. Otherwise, the tomcat open port cannot be perceived. Q: If you use the tomcat method to integrate the ServiceComb microservices framework, how to register the context of the war package deployment to the service center when the service is registered A: When publishing the service interface, you need to put the context of the war package deployment at the front of the baseurl, so that the path registered to the service center is the complete path (including the context). Example: java @path(/{context}/xxx) Class ServiceA Q: How does the ServiceComb microservices framework implement data transparent transmission between multiple microservices A: Transmitting data into: java CseHttpEntity<xxxx.class> httpEntity = new CseHttpEntity<>(xxx); / / Transparent content httpEntity.addContext(\"contextKey\",\"contextValue\"); ResponseEntity<String> responseEntity = RestTemplateBuilder.create().exchange(\"cse://springmvc/springmvchello/sayhello\",HttpMethod.POST, httpEntity, String.class); Transparent data acquisition: java @Override @RequestMapping(path=\"/sayhello\",method = RequestMethod.POST) Public String sayHello(@RequestBody Person person, InvocationContext context){ / / Transparent data acquisition context.getContext(); Return \"Hello person \" + person.getName(); } Q: How does the ServiceComb microservices framework service customize the return status code? A: java @Override @RequestMapping(path = \"/sayhello\",method = RequestMethod.POST) Public String sayHello(@RequestBody Person person){ InvocationContext context = ContextUtils.getInvocationContext(); / / Custom status code context.setStatus(Status.CREATED); Return \"Hello person \"+person.getName(); } Q: Partial exposure of ServiceComb body Model A: There may be some attributes in the body object corresponding to an interface. You don't want to open it. Do not bring it out when generating the schema. Use: java @ApiModelProperty(hidden = true) Q: ServiceComb framework gets the address of the remote consumer A: If you use the http rest method (using the transport-rest-vertx dependency) you can get it in the following way: java AbstractProducerContextArgMapper httpRequestCreator = (AbstractProducerContextArgMapper)invocation.getHandlerContext().get(RestConst.HTTP_REQUEST_CREATOR); If(httpRequestCreator != null){ HttpServletRequest req = (HttpServletRequest)httpRequestCreator.createContextArg(invocation); System.out.println(req.getRemoteHost()); } The actual scenario is to take the outermost address, so LB should be passed to edgeservice, and edgeService should be passed outside the context. Q: ServiceComb describes the handler A: The consumer default handler is simpleLB. When there is no configuration, the handler chain will use this. If the handler is configured, it must contain the lb handler. Otherwise, the call error is reported in the document. Q: ServiceComb log replacement A: CSE java-chassis log recommendation method is to use Log4jUtils.init() at startup, directly use the recommended Log4j for log management, but some scenarios do not want to use log4j, such as want to use log4j2 or logback, below log4j2 Take a brief introduction to the next step: 1. Do not use Log4jUtils.init() in the code; 2. Remove the log4j configuration file (it doesn't matter if you don't delete it, because it won't be used); 3. Exclude the log4j introduced by the CSE framework, for example: xml <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>provider-springmvc</artifactId> <exclusions> <exclusion> <groupId>log4j</groupId> <artifactId>log4j</artifactId> </exclusion> </exclusions> </dependency> 4. Introducing the dependency of log4j2 xml <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> </dependency> If there is no version dependency management, you need to fill in the version number. 5. Add the log4j2 configuration file log4j2.xml. Please check the official description for this, for example: xml <?xml version=\"1.0\" encoding=\"UTF-8\"?> <!--Log level and priority ordering: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL --> <!--Configuration behind the configuration, this is used to set the internal information output of log4j2, can not be set, when set to trace, you will see various detailed output inside log4j2 --> <!--monitorInterval: Log4j can automatically detect the modified configuration file and reconfigure itself, set the interval seconds --> <configuration status=\"WARN\" monitorInterval=\"30\"> <!--First define all appender--> <appenders> <!--This output console configuration --> <console name=\"Console\" target=\"SYSTEM_OUT\"> <!--Format of output log --> <PatternLayout pattern=\"[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n\"/> </console> <!--The file will print out all the information, this log will be automatically cleared every time the program is run, determined by the append attribute, this is also very useful, suitable for temporary testing --> <File name=\"log\" fileName=\"log/test.log\" append=\"false\"> <PatternLayout pattern=\"%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n\"/> </File> <!-- This will print out all info and the following level information. Each time the size exceeds the size, the size of the log will be automatically saved under the folder created by the year-month and compressed, as an archive --> <RollingFile name=\"RollingFileInfo\" fileName=\"${sys:user.home}/logs/info.log\" filePattern=\"${sys:user.home}/logs/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log\"> <!--The console only outputs level and above information (onMatch), other direct rejection (onMismatch) --> <ThresholdFilter level=\"info\" onMatch=\"ACCEPT\" onMismatch=\"DENY\"/> <PatternLayout pattern=\"[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n\"/> <Policies> <TimeBasedTriggeringPolicy/> <SizeBasedTriggeringPolicy size=\"100 MB\"/> </Policies> </RollingFile> <RollingFile name=\"RollingFileWarn\" fileName=\"${sys:user.home}/logs/warn.log\" filePattern=\"${sys:user.home}/logs/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log\"> <ThresholdFilter level=\"warn\" onMatch=\"ACCEPT\" onMismatch=\"DENY\"/> <PatternLayout pattern=\"[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n\"/> <Policies> <TimeBasedTriggeringPolicy/> <SizeBasedTriggeringPolicy size=\"100 MB\"/> </Policies> <!-- DefaultRolloverStrategy property is not set, the default is up to 7 files in the same folder, here set 20 --> <DefaultRolloverStrategy max=\"20\"/> </RollingFile> <RollingFile name=\"RollingFileError\" fileName=\"${sys:user.home}/logs/error.log\" filePattern=\"${sys:user.home}/logs/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log\"> <ThresholdFilter level=\"error\" onMatch=\"ACCEPT\" onMismatch=\"DENY\"/> <PatternLayout pattern=\"[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n\"/> <Policies> <TimeBasedTriggeringPolicy/> <SizeBasedTriggeringPolicy size=\"100 MB\"/> </Policies> </RollingFile> </appenders> <!-- Then define the logger, the appender will only take effect if the appender is defined and imported -> <loggers> <!--Filter out some useless DEBUG information from spring and mybatis --> <logger name=\"org.springframework\" level=\"INFO\"></logger> <logger name=\"org.mybatis\" level=\"INFO\"></logger> <root level=\"all\"> <appender-ref ref=\"Console\"/> <appender-ref ref=\"RollingFileInfo\"/> <appender-ref ref=\"RollingFileWarn\"/> <appender-ref ref=\"RollingFileError\"/> </root> </loggers> </configuration> 6. Start the service for verification Q: Service timeout setting A: Add the following configuration to the microservice description file (microservice.yaml): yaml servicecomb: request: timeout: 30000 Q: The URL address can be uniquely located. Why do you want to add a schema? A: 1. The schema is used to match the service contract. It is used to ensure that the server and the consumer contract are compatible. Each contract needs a unique ID and is stored in the service center. 2. Schema maps to the interface concept of java. When the consumer uses the transparent rpc mode to develop, it can find which operation in the micro service. The method names between schemas are not unique. 3. operation qualified name is the key of the governance, and the URL cannot be directly searched because of the existence of the path parameter, and the qualified name will not change. Governance does not distinguish between transmissions. If governance goes by URL, then when highway is called in, it has to construct the url according to the parameters, and then the regular expression matches, which is too tossing. 4. http is just a transport channel, and there are other transport channels that do not need to be mapped to URLs. Q: When the Rest client is invocating, it only takes the service name and URL, and does not need to specify the schema id. In fact, according to this URL, the specific contract can also be found. So what is the role of the specified schema id? A: Since transparent rpc is an interface call and does not have a URL, the internal is actually normalized to the operation to describe, so that it can be uniquely mapped to the specific request processing in conjunction with the schema id. Q: What is the concept of Transport? What is it used for? A: The Transport is responsible for codec, and transmission. The communication model has two kinds of Rest and Highway. The Highway corresponds to the private protocol, which uses protobuf encoding, and the Rest uses json. Highway and Rest are based on vertx, and vertx is based on netty. Q: Is there be multiple appIDs and microservices in a service provider? What scenario will this happen? A: Yes, what is expressed here is a concept of merge. The microservice.yaml file, which may exist in both jars, disks, and command line arguments, specifies that they are merged by priority and are used for added flexibility. In the jar is the default value, in addition to the environment variables, command line parameters, configuration center coverage, providing multiple layers of customization. Q: How does ServiceComb interact with the service center? A: Take the rest, mainly responsible for registration, taking data and heartbeat, etc.; 'watch event' via websocket, watch event is to observe whether the service center instance information has changed. Q: Is there a governance center like dubbo? A: bizkeeper is a handler, one of the contents of governance. Governance can be extended by handlers. Q: How to understand the service path? A: Each microservice has a servicePathManager, and each schema registers its own path. Q: Can the browser directly access the microservice Endpoint? A: Yes, the restful microservice Endpoint can be used to access the service that provides the get method directly in the browser using HTTP plus service path. If it is to access the services provided by other Http methods, it is recommended to install and use.(https://www.sap.com/developer/tutorials/api-tools-postman-install.html) Q: When the contract is generated, do you have to add the version number and language? A: The contract belongs to the microservice. The microservice has a version, but the language should not be accompanied by the version number. Contractual requirements should be independent of language. The contract \"no version\", the version of the contract is embodied in the microservice, the instance can find the version of the microservice to which it belongs, and a certain contract can be found. Q: The design code in ServiceRegistry is similar to Eureka? A: Our first version was built on the basis of Spring Cloud. Later, when we found that it was not enough to use it, we gradually made our own set, so it was designed after fully referring to Eureka. Q: Some rpc is netty calling redis implementation, what is the advantage over direct netty forwarding? A: Maybe I want to use Redis to solve the subscription release. But this is not a big deal. I tried it before, but later I changed it to ServiceComb. Q: If you introduce the transport-rest-servlet and transport-rest-vertx dependencies at the same time, how does it decide which one to use? A: If the port is not occupied, use vertx; if it is occupied, use servlet. Q: What is the scenario for qps flow control design? A: Rate limit has two main functions. First, it guarantees the service effect to some key services by restricting different consumers, and the second is to prevent the avalanche effect. The thickness of the water pipe can be determined according to the importance of the service. ServiceComb supports two types of current limiting methods, namely, consumer-side current limiting and server-side current limiting. The consumer-side current limiting can achieve relatively fine control. Q: If the server is a chain call, that is, a->b->c, then does the QPS flow control cause flow pipe uneven and unbalanced? A: The general mode is to measure and then set. The qps settings are ultimately tuned in conjunction with the overall business needs, rather than setting them up on a single node. Q: The service failed to be invoked via cse://serviceName/appPath, error: java.lang.Error:not support def type:class io.swagger.models.properties xxx A: Check whether the version of java-chassis that the consumer and provider depend on are consistent. If they are inconsistent, please modify and use the newer version. Q: When sending a rest request, the following error is reported: Bad Request, description: http:request body too large A: Check if the Service Center is older version, and if so, upgrade to the latest version. Q: How to ignore the attributes specified in the contract DTO? A: If you are using 'rest transport', because it is Json serialization, you can use @JsonIgnore annotations to mark attributes that need to be ignored; 'highway transport' is not currently supported. Note that you need to update the version of the microservice after the modification, for example: java public class OutputForTest{ @JsonIgnore private String outputId = null; private String inputId = null; ... } Q: How to get the value of a field in the header in a user-defined handler A: Use the @ApiImplicitParams annotation declaration in the user-defined handler and the invocation.getArgs() to get the value of the header. E.g: java public class MyHandler implements Handler { @ApiImplicitParams({@ApiImplicitParam(name = \"tester\", dataType = \"string\", paramType = \"header\")}) @Override public void handle(Invocation invocation, AsyncResponse asyncResp) throws Exception { Object[] args = invocation.getArgs(); System.out.println(args); } } Q: The exception is thrown when the microservices runtime: java.lang.Error:not support def type:calss io.swagger.models.properties BaseIntegerProperty ? A: Service Center can be upgraded to version 4.0.0+ to solve [Service Center latest version portal] (http://apache.org/dyn/closer.cgi/incubator/servicecomb/incubator-servicecomb-service-center /1.0.0-m1/). . Q: Our API can not be accessed after microservices are up. It just returns 404 Not Found . The codes we use is as follows: * java @RestController @RestSchema(schemaId = \"worker\") public class WorkerController { @RequestMapping(value=\"/count\", method=RequestMethod.GET) public int getWorkerNumbers() { ... } } A: Without specifying the base path, ServiceComb will use the classname as the base path. Hence, the path should be /WorkerController/count in the previous code. If you want to access path like /count , you need to specify base path as / as follows: java @RequestMapping(value = \"/\") public class WorkerController {} . Q: What\\'s the default base path if I have not declared the value of RequestMapping annotation? * A: Supposed the class name of your controller is HelloController , the base path is /HelloController.","title":"FAQ"},{"location":"question-and-answer/interface-compatibility/","text":"In the process of continuous iterative development of microservices, due to the continuous addition of new features, some old features are continually being modified, and interface compatibility issues face enormous challenges, especially in the running environment multi-version coexistence (grayscale release) ). This chapter mainly describes some practical suggestions for interface compatibility management and solutions to compatibility problems during use. Since microservices generally provide services externally through the REST interface, the interface here refers to the REST interface without special instructions. Practice of ensuring interface compatibility To prevent interface compatibility problems, developers are advised to follow the following principles when making interface changes (add, modify, delete, etc.). Only add interfaces, do not modify or delete interfaces. As a Provider, when adding an interface, the microservice version number is incremented accordingly. For example, change 2.1.2 to 2.1.3. As a Consumer, when using the new interface of the Provider, specify the minimum version number of the Provider. For example: servicecomb.references.[serviceName].version-rule=2.1.3+, The serviceName is the Provider's microservice name. In the service center, regularly clean up the old version of microservice information that is no longer used. If microservice version number is not changed and when startup, the meta info in service center will not overridden. The Consumers see old meta data. To prevent this happen, ServiceComb will stop boot when incompatible interface change and version is the same. In newly developed project, use development environment to bypass this check. service_description: environment: development Please notice that consumer is also need reboot or old interface metadata will be used. interface compatibility common problems and their solutions During the development phase, due to various interface modification, the data of the service center would not be cleaned up, and the interface call fails when debugging. Developers are advised to install and download a [frontend] of the service center (http://apache.org/dyn/closer.cgi/incubator/servicecomb/incubator-servicecomb-service-center/1.0.0-m1/), anytime Clean up service center data. If you use Huawei's public cloud online service center, you can log in directly using the management functions provided by the microservice engine to delete. During the release phase, you need to review the steps of the interface-compatible practices to ensure that interface compatibility issues are not online. If you accidentally miss one of these steps, it may lead to the following interface compatibility issues: If the interface is modified or deleted: some old Consumers will fail to request the new route of the new Provider. If you forget to modify the microservice version number: some new Consumers will fail to request the route of the old Provider. If you forget to configure the minimum dependent version of the Consumer: when the deployment order is to stop the Consumer first, then start the Consumer, then stop the Provider, and then start the Provider. The Consumer cannot obtain the new interface information, and the old interface is used. When the Provider starts, The Consumer initiates a call to the new interface that fails; or fails to call the new interface before the Provider started. Workarounds for problems: There are different interface compatibility issues and different handling methods. In extreme cases, you only need to clean up the Provider and Consumer microservices, and then restart the microservice. When the service call relationship is complexed, the interface compatibility problem will be more extensive and clean the Provider, and Consumer data will become complicated. Therefore, it is recommended to follow the above specifications to avoid incompatibility.","title":"Micro Service Interface Compatibility FAQ"},{"location":"question-and-answer/interface-compatibility/#practice-of-ensuring-interface-compatibility","text":"To prevent interface compatibility problems, developers are advised to follow the following principles when making interface changes (add, modify, delete, etc.). Only add interfaces, do not modify or delete interfaces. As a Provider, when adding an interface, the microservice version number is incremented accordingly. For example, change 2.1.2 to 2.1.3. As a Consumer, when using the new interface of the Provider, specify the minimum version number of the Provider. For example: servicecomb.references.[serviceName].version-rule=2.1.3+, The serviceName is the Provider's microservice name. In the service center, regularly clean up the old version of microservice information that is no longer used. If microservice version number is not changed and when startup, the meta info in service center will not overridden. The Consumers see old meta data. To prevent this happen, ServiceComb will stop boot when incompatible interface change and version is the same. In newly developed project, use development environment to bypass this check. service_description: environment: development Please notice that consumer is also need reboot or old interface metadata will be used.","title":"Practice of ensuring interface compatibility"},{"location":"question-and-answer/interface-compatibility/#interface-compatibility-common-problems-and-their-solutions","text":"During the development phase, due to various interface modification, the data of the service center would not be cleaned up, and the interface call fails when debugging. Developers are advised to install and download a [frontend] of the service center (http://apache.org/dyn/closer.cgi/incubator/servicecomb/incubator-servicecomb-service-center/1.0.0-m1/), anytime Clean up service center data. If you use Huawei's public cloud online service center, you can log in directly using the management functions provided by the microservice engine to delete. During the release phase, you need to review the steps of the interface-compatible practices to ensure that interface compatibility issues are not online. If you accidentally miss one of these steps, it may lead to the following interface compatibility issues: If the interface is modified or deleted: some old Consumers will fail to request the new route of the new Provider. If you forget to modify the microservice version number: some new Consumers will fail to request the route of the old Provider. If you forget to configure the minimum dependent version of the Consumer: when the deployment order is to stop the Consumer first, then start the Consumer, then stop the Provider, and then start the Provider. The Consumer cannot obtain the new interface information, and the old interface is used. When the Provider starts, The Consumer initiates a call to the new interface that fails; or fails to call the new interface before the Provider started. Workarounds for problems: There are different interface compatibility issues and different handling methods. In extreme cases, you only need to clean up the Provider and Consumer microservices, and then restart the microservice. When the service call relationship is complexed, the interface compatibility problem will be more extensive and clean the Provider, and Consumer data will become complicated. Therefore, it is recommended to follow the above specifications to avoid incompatibility.","title":"interface compatibility common problems and their solutions"},{"location":"question-and-answer/question_answer/","text":"Problem: How to customize the HTTP status code in the REST interface corresponding to a Java method? Solution: For normal return values, this can be done with SwaggerAnnotation, for example: @ApiResponse(code = 300, response = String.class, message = \"\") public int test(int x) { return 100; } For the return value of the exception, you can do this by throwing a custom InvocationException, for example: public String testException(int code) { String strCode = String.valueOf(code); switch (code) { case 200: return strCode; case 456: throw new InvocationException(code, strCode, strCode + \" error\"); case 556: throw new InvocationException(code, strCode, Arrays.asList(strCode + \" error\")); case 557: throw new InvocationException(code, strCode, Arrays.asList(Arrays.asList(strCode + \" error\"))); default: break; } return \"not expected\"; } Problem: How to customize the log configuration of your own microservice Solution: ServiceComb does not bind the logger, use slf4j, users can freely choose log4j/log4j2/logback and so on. ServiceComb provides a log4j extension that supports incremental configuration of log4j's properties files on a standard log4j basis. By default, the configuration file is loaded from the path: \"classpath*:config/log4j.properties\" It will actually search all the config/log4j.properties and config/log4j.*.properties in the classpath, cut out the \\* part from the searched file, sort the alpha, then load it in order, and finally compose The file is used as the log4j configuration file. If you want to use ServiceComb's log4j extension, you need to call Log4jUtils.init, otherwise it will be used according to the rules of the standard logger. Problem: When the service is configured with multiple types of transport, What are the mechanisms for ServiceComb choose which transport to use at runtime? Solution: ServiceComb's consumer, transport, handler, and producer are decoupled. The functions work together through contract definitions, that is, whether the consumer uses transparent rpc, or springmvc develops and uses a highway, or RESTful does not transmit on the network. Relationships and producers use transparent rpc, or jaxrs, or springmvc development, and there is no relationship between the receiver and the perception, business development methods and transmission methods. Consumer access producer, in the runtime transport selection, the general rule is: the consumer's transport and producer's endpoint intersection, if there are multiple transports after the intersection, then use in turn Decomposed, there are the following scenarios: When a microservice producer provided both the highway and the RESTful endpoint Only the highway transport jar is deployed in the consumer process, only the producer's highway endpoint is accessed. * Only the RESTful transport jar is deployed in the consumer process, only the RESTful endpoint of the producer is accessed. * The consumer process, while deploying the highway and RESTful transport jar, will take turns accessing the producer's highway, RESTful endpoint If at this time, the consumer wants to use a transport to access the producer, it can be configured in the microservice.yaml of the consumer process, specifying the name of the transport: servicecomb: references: transport: <service_name>: highway When a microservice producer only provided the endpoint of the highway * The consumer process only deploys the highway transport jar, and normally uses higway endpoint. * The consumer process can only be accessed if only the RESTful transport jar is deployed * The consumer process deploys both the highway and the RESTful transport jar, and the highway access is normally used. When a microservice producer only provided RESTful endpoints * The consumer process only deploys the highway transport jar and cannot access it. * The consumer process only deploys RESTful transport jars, which normally use RESTful access * The consumer process deploys both the highway and the RESTful transport jar, and the RESTful access is normally used. Problem: The swagger body parameter type is incorrectly defined, resulting in no content information for the content registered by the service center. Symptom: Define the following interface, put the parameters into the body to pass /testInherate: post: operationId: \"testInherate\" parameters: - in: \"body\" name: \"xxxxx\" required: false type: string responses: 200: description: \"response of 200\" schema: $ref: \"#/definitions/ReponseImpl\" Define the interface in the above way. After the service is registered, the interface type: a string that is queried from the service center is lost and becomes: /testInherate: post: operationId: \"testInherate\" parameters: - in: \"body\" name: \"xxxxx\" required: false responses: 200: description: \"response of 200\" schema: $ref: \"#/definitions/ReponseImpl\" If the client does not place a swagger, the following exception is also reported: Caused by: java.lang.ClassFormatError: Method \"testInherate\" in class ? has illegal signature. \" Solution: When defining the type of the body parameter, you can't use type directly instead use the schema. /testInherate: post: operationId: \"testInherate\" parameters: - in: \"body\" name: \"request\" required: false schema: type: string responses: 200: description: \"response of 200\" schema: $ref: \"#/definitions/ReponseImpl\" Problem: Does the microservices framework service call use long live connection? Solution: Http uses a long connection (with a timeout), and the highway mode uses a long connection (always on). Problem: When the service is disconnected from the service center, will the registration information be deleted automatically? Solution: The service center heartbeat detects that the service instance is unavailable, only the service instance information is removed, and the static data of the service is not removed. Problem: How does the microservices framework achieve transparent transmission of data between multiple microservices? Solution: Transmitting data into: CseHttpEntity<xxxx.class> httpEntity = new CseHttpEntity<>(xxx); //Transmission content httpEntity.addContext(\"contextKey\",\"contextValue\"); ResponseEntity<String> responseEntity = RestTemplateBuilder.create().exchange(\"cse://springmvc/springmvchello/sayhello\",HttpMethod.POST,httpEntity,String.class); Transparent data acquisition: @Override @RequestMapping(path=\"/sayhello\",method = RequestMethod.POST) public String sayHello(@RequestBody Person person,InvocationContext context){ //Transparent data acquisition context.getContext(); return \"Hello person \" + person.getName(); } Problem: How the microservices framework service customizes the return status code Solution: @Override @RequestMapping(path = \"/sayhello\",method = RequestMethod.POST) public String sayHello(@RequestBody Person person){ InvocationContext context = ContextUtils.getInvocationContext(); //\u81ea\u5b9a\u4e49\u72b6\u6001\u7801 context.setStatus(Status.CREATED); return \"Hello person \"+person.getName(); } Problem: Partial exposure of body Model Solution: In the body object corresponding to an interface, there may be some attributes that are internal. Do not want to open it. Do not bring it out when generating the schema. Use: @ApiModelProperty(hidden = true) Problem: The framework obtains the address of the remote consumer Solution: If you use the http rest method (using the transport-rest-vertx dependency) you can get it in the following way: HttpServletRequest request = (HttpServletRequest) invocation.getHandlerContext().get(RestConst.REST_REQUEST); String host = request.getRemoteHost(); The actual scene is to take the external address, so it should be LB passed to edgeservice, and edgeService is then passed to the context and passed. Problem: Description of the handler Solution: Consumer default handler is simpleLB, and the handler chain will use this when there is no configuration, if the handler is configured, it must contain the lb handler. Otherwise the call error, need to be described in the document. Problem: Netty version problem Solution: Netty3 and netty4 are completely different tripartites because the coordinates are not the same as the package, so they can coexist, but pay attention to the minor version problem, the version that the small version must use. Problem: Service Timeout Settings Solution: Add the following configuration to the microservice description file (microservice.yaml): servicecomb: request: timeout: 30000 Problem: Is there a required for the processing chain's sequence of service governance? Solution: The order of the processing chains is different, and the system works differently. List the common questions below. 1, loadbalance and bizkeeper-consumer These two sequences can be combined randomly. But the behavior is different. When loadbalance is in the front, the retry function provided by loadbalance will occur when bizkeeper-consumer throws an exception, such as timeout. But if you have done a fallback policy configuration, such as return null, then loadbalance will not retry. If loadbalance is behind, the retry will extend the timeout. Even if the retry is successful, if the timeout period set by bizkeeper-consumer is not enough, the final call result will also fail. 2, tracing-consumer, sla-consumer, tracing-provider, sla-provider These processing chains are recommended to be placed at the very beginning of the processing chain to ensure that the success and failure of the log can be recorded (because the log requires IP and other information, for consumers, can only be placed behind the loadbalance). If you do not need to record the exception returned by the client, you can put it to the end and only pay attention to the error returned by the network layer. However, if the bizkeeper-consumer timeout returns earlier, the log may not be logged. Suggested order Consumer: loadbalance, tracing-consumer, sla-consumer, bizkeeper-consumer Provider: tracing-provider, sla-provider, bizkeeper-provider This order is sufficient for most scenarios and is not easy to cause errors. Problem: the meaning of config item servicecomb.uploads.maxSize in file uploading config item: servicecomb.uploads.maxSize meaning: The maximum allowable size of http body in bytes, the default value of -1 means unlimited.","title":"Q & A"},{"location":"question-and-answer/question_answer/#problem-how-to-customize-the-http-status-code-in-the-rest-interface-corresponding-to-a-java-method","text":"Solution: For normal return values, this can be done with SwaggerAnnotation, for example: @ApiResponse(code = 300, response = String.class, message = \"\") public int test(int x) { return 100; } For the return value of the exception, you can do this by throwing a custom InvocationException, for example: public String testException(int code) { String strCode = String.valueOf(code); switch (code) { case 200: return strCode; case 456: throw new InvocationException(code, strCode, strCode + \" error\"); case 556: throw new InvocationException(code, strCode, Arrays.asList(strCode + \" error\")); case 557: throw new InvocationException(code, strCode, Arrays.asList(Arrays.asList(strCode + \" error\"))); default: break; } return \"not expected\"; }","title":"Problem: How to customize the HTTP status code in the REST interface corresponding to a Java method?"},{"location":"question-and-answer/question_answer/#problem-how-to-customize-the-log-configuration-of-your-own-microservice","text":"Solution: ServiceComb does not bind the logger, use slf4j, users can freely choose log4j/log4j2/logback and so on. ServiceComb provides a log4j extension that supports incremental configuration of log4j's properties files on a standard log4j basis. By default, the configuration file is loaded from the path: \"classpath*:config/log4j.properties\" It will actually search all the config/log4j.properties and config/log4j.*.properties in the classpath, cut out the \\* part from the searched file, sort the alpha, then load it in order, and finally compose The file is used as the log4j configuration file. If you want to use ServiceComb's log4j extension, you need to call Log4jUtils.init, otherwise it will be used according to the rules of the standard logger.","title":"Problem: How to customize the log configuration of your own microservice"},{"location":"question-and-answer/question_answer/#problem-when-the-service-is-configured-with-multiple-types-of-transport-what-are-the-mechanisms-for-servicecomb-choose-which-transport-to-use-at-runtime","text":"Solution: ServiceComb's consumer, transport, handler, and producer are decoupled. The functions work together through contract definitions, that is, whether the consumer uses transparent rpc, or springmvc develops and uses a highway, or RESTful does not transmit on the network. Relationships and producers use transparent rpc, or jaxrs, or springmvc development, and there is no relationship between the receiver and the perception, business development methods and transmission methods. Consumer access producer, in the runtime transport selection, the general rule is: the consumer's transport and producer's endpoint intersection, if there are multiple transports after the intersection, then use in turn Decomposed, there are the following scenarios: When a microservice producer provided both the highway and the RESTful endpoint Only the highway transport jar is deployed in the consumer process, only the producer's highway endpoint is accessed. * Only the RESTful transport jar is deployed in the consumer process, only the RESTful endpoint of the producer is accessed. * The consumer process, while deploying the highway and RESTful transport jar, will take turns accessing the producer's highway, RESTful endpoint If at this time, the consumer wants to use a transport to access the producer, it can be configured in the microservice.yaml of the consumer process, specifying the name of the transport: servicecomb: references: transport: <service_name>: highway When a microservice producer only provided the endpoint of the highway * The consumer process only deploys the highway transport jar, and normally uses higway endpoint. * The consumer process can only be accessed if only the RESTful transport jar is deployed * The consumer process deploys both the highway and the RESTful transport jar, and the highway access is normally used. When a microservice producer only provided RESTful endpoints * The consumer process only deploys the highway transport jar and cannot access it. * The consumer process only deploys RESTful transport jars, which normally use RESTful access * The consumer process deploys both the highway and the RESTful transport jar, and the RESTful access is normally used.","title":"Problem: When the service is configured with multiple types of transport, What are the mechanisms for ServiceComb choose which transport to use at runtime?"},{"location":"question-and-answer/question_answer/#problem-the-swagger-body-parameter-type-is-incorrectly-defined-resulting-in-no-content-information-for-the-content-registered-by-the-service-center","text":"Symptom: Define the following interface, put the parameters into the body to pass /testInherate: post: operationId: \"testInherate\" parameters: - in: \"body\" name: \"xxxxx\" required: false type: string responses: 200: description: \"response of 200\" schema: $ref: \"#/definitions/ReponseImpl\" Define the interface in the above way. After the service is registered, the interface type: a string that is queried from the service center is lost and becomes: /testInherate: post: operationId: \"testInherate\" parameters: - in: \"body\" name: \"xxxxx\" required: false responses: 200: description: \"response of 200\" schema: $ref: \"#/definitions/ReponseImpl\" If the client does not place a swagger, the following exception is also reported: Caused by: java.lang.ClassFormatError: Method \"testInherate\" in class ? has illegal signature. \" Solution: When defining the type of the body parameter, you can't use type directly instead use the schema. /testInherate: post: operationId: \"testInherate\" parameters: - in: \"body\" name: \"request\" required: false schema: type: string responses: 200: description: \"response of 200\" schema: $ref: \"#/definitions/ReponseImpl\"","title":"Problem: The swagger body parameter type is incorrectly defined, resulting in no content information for the content registered by the service center."},{"location":"question-and-answer/question_answer/#problem-does-the-microservices-framework-service-call-use-long-live-connection","text":"Solution: Http uses a long connection (with a timeout), and the highway mode uses a long connection (always on).","title":"Problem: Does the microservices framework service call use long live connection?"},{"location":"question-and-answer/question_answer/#problem-when-the-service-is-disconnected-from-the-service-center-will-the-registration-information-be-deleted-automatically","text":"Solution: The service center heartbeat detects that the service instance is unavailable, only the service instance information is removed, and the static data of the service is not removed.","title":"Problem: When the service is disconnected from the service center, will the registration information be deleted automatically?"},{"location":"question-and-answer/question_answer/#problem-how-does-the-microservices-framework-achieve-transparent-transmission-of-data-between-multiple-microservices","text":"Solution: Transmitting data into: CseHttpEntity<xxxx.class> httpEntity = new CseHttpEntity<>(xxx); //Transmission content httpEntity.addContext(\"contextKey\",\"contextValue\"); ResponseEntity<String> responseEntity = RestTemplateBuilder.create().exchange(\"cse://springmvc/springmvchello/sayhello\",HttpMethod.POST,httpEntity,String.class); Transparent data acquisition: @Override @RequestMapping(path=\"/sayhello\",method = RequestMethod.POST) public String sayHello(@RequestBody Person person,InvocationContext context){ //Transparent data acquisition context.getContext(); return \"Hello person \" + person.getName(); }","title":"Problem: How does the microservices framework achieve transparent transmission of data between multiple microservices?"},{"location":"question-and-answer/question_answer/#problem-how-the-microservices-framework-service-customizes-the-return-status-code","text":"Solution: @Override @RequestMapping(path = \"/sayhello\",method = RequestMethod.POST) public String sayHello(@RequestBody Person person){ InvocationContext context = ContextUtils.getInvocationContext(); //\u81ea\u5b9a\u4e49\u72b6\u6001\u7801 context.setStatus(Status.CREATED); return \"Hello person \"+person.getName(); }","title":"Problem: How the microservices framework service customizes the return status code"},{"location":"question-and-answer/question_answer/#problem-partial-exposure-of-body-model","text":"Solution: In the body object corresponding to an interface, there may be some attributes that are internal. Do not want to open it. Do not bring it out when generating the schema. Use: @ApiModelProperty(hidden = true)","title":"Problem: Partial exposure of body Model"},{"location":"question-and-answer/question_answer/#problem-the-framework-obtains-the-address-of-the-remote-consumer","text":"Solution: If you use the http rest method (using the transport-rest-vertx dependency) you can get it in the following way: HttpServletRequest request = (HttpServletRequest) invocation.getHandlerContext().get(RestConst.REST_REQUEST); String host = request.getRemoteHost(); The actual scene is to take the external address, so it should be LB passed to edgeservice, and edgeService is then passed to the context and passed.","title":"Problem: The framework obtains the address of the remote consumer"},{"location":"question-and-answer/question_answer/#problem-description-of-the-handler","text":"Solution: Consumer default handler is simpleLB, and the handler chain will use this when there is no configuration, if the handler is configured, it must contain the lb handler. Otherwise the call error, need to be described in the document.","title":"Problem: Description of the handler"},{"location":"question-and-answer/question_answer/#problem-netty-version-problem","text":"Solution: Netty3 and netty4 are completely different tripartites because the coordinates are not the same as the package, so they can coexist, but pay attention to the minor version problem, the version that the small version must use.","title":"Problem: Netty version problem"},{"location":"question-and-answer/question_answer/#problem-service-timeout-settings","text":"Solution: Add the following configuration to the microservice description file (microservice.yaml): servicecomb: request: timeout: 30000","title":"Problem: Service Timeout Settings"},{"location":"question-and-answer/question_answer/#problem-is-there-a-required-for-the-processing-chains-sequence-of-service-governance","text":"Solution: The order of the processing chains is different, and the system works differently. List the common questions below. 1, loadbalance and bizkeeper-consumer These two sequences can be combined randomly. But the behavior is different. When loadbalance is in the front, the retry function provided by loadbalance will occur when bizkeeper-consumer throws an exception, such as timeout. But if you have done a fallback policy configuration, such as return null, then loadbalance will not retry. If loadbalance is behind, the retry will extend the timeout. Even if the retry is successful, if the timeout period set by bizkeeper-consumer is not enough, the final call result will also fail. 2, tracing-consumer, sla-consumer, tracing-provider, sla-provider These processing chains are recommended to be placed at the very beginning of the processing chain to ensure that the success and failure of the log can be recorded (because the log requires IP and other information, for consumers, can only be placed behind the loadbalance). If you do not need to record the exception returned by the client, you can put it to the end and only pay attention to the error returned by the network layer. However, if the bizkeeper-consumer timeout returns earlier, the log may not be logged. Suggested order Consumer: loadbalance, tracing-consumer, sla-consumer, bizkeeper-consumer Provider: tracing-provider, sla-provider, bizkeeper-provider This order is sufficient for most scenarios and is not easy to cause errors.","title":"Problem: Is there a required for the processing chain's sequence of service governance?"},{"location":"question-and-answer/question_answer/#problem-the-meaning-of-config-item-servicecombuploadsmaxsize-in-file-uploading","text":"config item: servicecomb.uploads.maxSize meaning: The maximum allowable size of http body in bytes, the default value of -1 means unlimited.","title":"Problem: the meaning of config item servicecomb.uploads.maxSize in file uploading"},{"location":"references-handlers/intruduction/","text":"Handlers Reference Handlers are the core components of ServiceComb, which form the basis of service operation and control. ServiceComb handles load balancing, fuse tolerance, flow control, and more through the Handlers. Enable Handlers There are Consumer Handlers and Provider Handlers. Enable handlers in microservice.yaml: servicecomb: handler: chain: Consumer: default: qps-flowcontrol-consumer,loadbalance Provider: default: qps-flowcontrol-provider We can also enable different handlers for each microservice, servicecomb: handler: chain: Consumer: default: auth,qps-flowcontrol-consumer,loadbalance service: authentication-server: qps-flowcontrol-consumer,loadbalance Requests to authentication-server, auth handler is enabled, and others not. Development Handlers The developer's custom handlers consists of the following steps. Since the core component of ServiceComb is the handlers, developers can refer to the implementation of the handlers directory to learn more about the Handlers. Here are a few key steps to summarize: Implement Handler interface public class AuthHandler implements Handler { @Override public void handle(Invocation invocation, AsyncResponse asyncResponse) throws Exception { String token = invocation.getContext(Constants.CONTEXT_HEADER_AUTHORIZATION); if (token == null) { asyncResponse.consumerFail(new InvocationException(403, \"forbidden\", \"not authenticated\")); return; } Jwt jwt = JwtHelper.decode(token); try { jwt.verifySignature(BeanUtils.getBean(\"authSigner\")); } catch (InvalidSignatureException e) { asyncResponse.consumerFail(new InvocationException(403, \"forbidden\", \"not authenticated\")); return; } invocation.next(asyncResponse); } } Add *.handler.xml file, give handler a name <config> <handler id=\"auth\" class=\"org.apache.servicecomb.authentication.gateway.AuthHandler\" /> </config> Enable the newly added Handlers in microservice.yaml servicecomb: handler: chain: Consumer: default: auth,loadbalance service: authentication-server: loadbalance","title":"Intruductions"},{"location":"references-handlers/intruduction/#handlers-reference","text":"Handlers are the core components of ServiceComb, which form the basis of service operation and control. ServiceComb handles load balancing, fuse tolerance, flow control, and more through the Handlers.","title":"Handlers Reference"},{"location":"references-handlers/intruduction/#enable-handlers","text":"There are Consumer Handlers and Provider Handlers. Enable handlers in microservice.yaml: servicecomb: handler: chain: Consumer: default: qps-flowcontrol-consumer,loadbalance Provider: default: qps-flowcontrol-provider We can also enable different handlers for each microservice, servicecomb: handler: chain: Consumer: default: auth,qps-flowcontrol-consumer,loadbalance service: authentication-server: qps-flowcontrol-consumer,loadbalance Requests to authentication-server, auth handler is enabled, and others not.","title":"Enable Handlers"},{"location":"references-handlers/intruduction/#development-handlers","text":"The developer's custom handlers consists of the following steps. Since the core component of ServiceComb is the handlers, developers can refer to the implementation of the handlers directory to learn more about the Handlers. Here are a few key steps to summarize: Implement Handler interface public class AuthHandler implements Handler { @Override public void handle(Invocation invocation, AsyncResponse asyncResponse) throws Exception { String token = invocation.getContext(Constants.CONTEXT_HEADER_AUTHORIZATION); if (token == null) { asyncResponse.consumerFail(new InvocationException(403, \"forbidden\", \"not authenticated\")); return; } Jwt jwt = JwtHelper.decode(token); try { jwt.verifySignature(BeanUtils.getBean(\"authSigner\")); } catch (InvalidSignatureException e) { asyncResponse.consumerFail(new InvocationException(403, \"forbidden\", \"not authenticated\")); return; } invocation.next(asyncResponse); } } Add *.handler.xml file, give handler a name <config> <handler id=\"auth\" class=\"org.apache.servicecomb.authentication.gateway.AuthHandler\" /> </config> Enable the newly added Handlers in microservice.yaml servicecomb: handler: chain: Consumer: default: auth,loadbalance service: authentication-server: loadbalance","title":"Development Handlers"},{"location":"references-handlers/loadbalance/","text":"load balancing Scenario ServiceComb provides very powerful load balancing capabilities, which consists of two core parts. The first part DiscoveryTree, whose core part is DiscoveryFilter, groups microservice instances by their interface compatibility, data center, status, etc. The second part is the load balancing scheme based on Ribbon, which supports various load balancing policies(IRule) include random, sequential, response time-based weights, and ServerListFilterExt which is based on Invocation state. DiscoveryTree's logic is more complex, its processing progress is as below: Load balancing can be configured in the Consumer processing chain, the handler name is loadbalance, as follows: servicecomb: handler: chain: Consumer: default: loadbalance POM dependence: <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>handler-loadbalance</artifactId> </dependency> Routing and forwarding by data center information Service providers and consumers can declare their service center information in microservice.yaml: servicecomb: datacenter: name: mydatacenter region: my-Region availableZone: my-Zone Consumers compare their own data center information and providers' information, preferentially forward the request to the provider instance in the same region and availableZone; if the target instance is not available, it forwards request to the instance in the same region; if the target still does not exist, it forwards requests to other instances. The region and availableZone here are general concepts, users can determine their business meanings to apply them to resource-isolated scenarios. See Logical isolation relationships between microservice instances for more details of the isolation. This rule is enabled by default. If it is not needed, set servicecomb.loadbalance.filter.zoneaware.enabled to false. Data center information isolation is implemented in ZoneAwareDiscoveryFilter. Routing and forwarding by instance attributes Users can specify the properties of microservice instances in microservice.yaml, or by calling service center APIs. instance_description: properties: tags: tag_key: tag_value Consumers can specify provider instances' attributes to determine which instances to call. servicecomb: loadbalance: # Here the \"provider\" means the config items below only take effect on the service named \"provider\" # In cross-app invocation, the AppID should be prefixed, like \"AppIDOfProvider:provider\" provider: transactionControl: options: tags: tag_key: expected_tag_value The above configuration shows that only the instances of \"provider\" with the tag attribute tag_key:expected_tag_value are called. This rule needs to be configured separately for each service. Global rule for all services is not supported. This rule is enabled by default, it can be disabled by setting servicecomb.loadbalance.filter.instanceProperty.enabled to false. The instance attributes based routing policy is implemented in InstancePropertyDiscoveryFilter . Routing and forwarding by instance attributes with hierarchy value This is a extension of the feature above. You can specify the properties of microservice instances in microservice.yaml with hierarchy value, which is separated by . symbol. instance_description: properties: KEY: a.b.c Consumer need to specify the key of instance which is used to match provider, the default key is environment servicecomb: loadbalance: filter: priorityInstanceProperty: key: KEY Assuming there is a consumer instance with property value a.b.c , the match priority of provider will be a.b.c > a.b > a > [empty] and the table shown below gives detail match priority. | consumer | match priority of provider| | :--- | :--- | |a.b.c|a.b.c>a.b>a>[empty]| |a.b|a.b>a>[empty]| |a|a>[empty]| |[empty]|[empty]| Note that [empty] is represent for the instances which is not set value of this property key This rule is NOT enabled by default, which can be enabled by setting servicecomb.loadbalance.filter.priorityInstanceProperty.enabled to true. The policy is implemented in PriorityInstancePropertyDiscoveryFilter . Instance isolation Developers can configure instance-isolated parameters to temporarily drop access to the wrong instance, improving system reliability and performance. Below are the configuration items and default values: servicecomb: loadbalance: isolation: enabled: true errorThresholdPercentage: 0 enableRequestThreshold: 5 singleTestTime: 60000 continuousFailureThreshold: 5 The interval of isolation calculation is 1 minute. According to the above configuration, in 1 minute, if the total number of requests is greater than 5, and more than 2 consecutive errors occur, the instance is isolated. The default value of errorThresholdPercentage is 0, indicates that the rule is ommited. The item should be a integer less than 100, for example 20, then within 1 minutes, if the total number of request is greater than 5 and [1] error rate is greater than 20% or [2] more than 2 consecutive errors occur, is instance is isolated. After 60 seconds, the instance will be re-enabled and accessible if it matches the rules of load balancing policy. Notes: When error rate reaches the threshold, is instance is isolated and the error rate will be calculated again after the interval. Then with the successful accesses, the rate will decrease and become less than the threshold, then instance is available again. Since the rate is calculated by number of requests, if the total requests reaches the threshold and the error rate is much greater than its threshold, the instance would take a long time to recover. ServiceComb starts a thread in the background to detect the instance state, and checks the instance state every 10 seconds (if the instance is accessed within 10 seconds, it is not detected). If the detection fails, the error number is accumulated with 1. The count here also affects instance isolation. The default instance state detection mechanism is to send a telnet instruction, refer to the implementation of SimpleMicroserviceInstancePing. Users can overwrite the status detection mechanism with the following two steps: Implement the MicroserviceInstancePing interface Configure SPI: Add META-INF/services/org.apache.servicecomb.serviceregistry.consumer.MicroserviceInstancePing, the content is the full path of the implementation class Developers can configure different isolation policies for different microservices. Just add a service name to the configuration item, for example: servicecomb: loadbalance: myservice: isolation: enabled: true errorThresholdPercentage: 20 enableRequestThreshold: 5 singleTestTime: 10000 continuousFailureThreshold: 2 This rule is enabled by default and can be turned off by setting servicecomb.loadbalance.filter.isolation.enabled to false. Data center information isolation is implemented in IsolationDiscoveryFilter. Configuring route rules Developers can specify load balancing policies through configuration items. servicecomb: loadbalance: strategy: name: RoundRobin # Support RoundRobin,Random,WeightedResponse,SessionStickiness Developers can configure policies for different microservices by adding a service name, for example: servicecomb: loadbalance: myservice: strategy: name: RoundRobin # Support RoundRobin,Random,WeightedResponse,SessionStickiness Each policy has some specific configuration items. SessionStickiness servicecomb: loadbalance: SessionStickinessRule: sessionTimeoutInSeconds: 30 # Client idle time, after the limit is exceeded, select the server behind successiveFailedTimes: 5 # The number of client failures will switch after the server is exceeded. Set retry strategy The load balancing module also supports the policy retry. servicecomb: loadbalance: retryEnabled: false retryOnNext: 0 retryOnSame: 0 Retry is not enabled by default. Developers can set different strategies for different services: servicecomb: loadbalance: myservice\uff1a retryEnabled: true retryOnNext: 1 retryOnSame: 0 retryOnNext indicates that after the failure, according to the load balancing policy, re-select an instance to retry (may choose the same instance), while retryOnSame means that the last failed instance is still used for retry. Customization The load balancing module provides various configurations that can support most application scenarios. It also provides flexible extension capabilities, including DiscoveryFilter, ServerListFilterExt, ExtensionsFactory (extension IRule, RetryHandler, etc.). The loadbalance module itself contains the implementation of each extension. The brief introduction of extending load balancing module is described below. Developers can download the ServiceComb source code to see the details. DiscoveryFilter Implement the DiscoveryFilter interface Configure SPI: Add META-INF/services/org.apache.servicecomb.serviceregistry.discovery.DiscoveryFilter file with the full path of the implementation class ServerListFilterExt Implement the ServerListFilterExt interface Configure SPI: Add META-INF/services/org.apache.servicecomb.loadbalance.ServerListFilterExt file, the content is the full pathof the implementation class Note: This instruction applies to version 1.0.0 and later. Earlier versions are extended in a different way. ExtensionsFactory Implement the ExtensionsFactory and publish it as a spring bean using @Component.","title":"Load Balancing"},{"location":"references-handlers/loadbalance/#load-balancing","text":"","title":"load balancing"},{"location":"references-handlers/loadbalance/#scenario","text":"ServiceComb provides very powerful load balancing capabilities, which consists of two core parts. The first part DiscoveryTree, whose core part is DiscoveryFilter, groups microservice instances by their interface compatibility, data center, status, etc. The second part is the load balancing scheme based on Ribbon, which supports various load balancing policies(IRule) include random, sequential, response time-based weights, and ServerListFilterExt which is based on Invocation state. DiscoveryTree's logic is more complex, its processing progress is as below: Load balancing can be configured in the Consumer processing chain, the handler name is loadbalance, as follows: servicecomb: handler: chain: Consumer: default: loadbalance POM dependence: <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>handler-loadbalance</artifactId> </dependency>","title":"Scenario"},{"location":"references-handlers/loadbalance/#routing-and-forwarding-by-data-center-information","text":"Service providers and consumers can declare their service center information in microservice.yaml: servicecomb: datacenter: name: mydatacenter region: my-Region availableZone: my-Zone Consumers compare their own data center information and providers' information, preferentially forward the request to the provider instance in the same region and availableZone; if the target instance is not available, it forwards request to the instance in the same region; if the target still does not exist, it forwards requests to other instances. The region and availableZone here are general concepts, users can determine their business meanings to apply them to resource-isolated scenarios. See Logical isolation relationships between microservice instances for more details of the isolation. This rule is enabled by default. If it is not needed, set servicecomb.loadbalance.filter.zoneaware.enabled to false. Data center information isolation is implemented in ZoneAwareDiscoveryFilter.","title":"Routing and forwarding by data center information"},{"location":"references-handlers/loadbalance/#routing-and-forwarding-by-instance-attributes","text":"Users can specify the properties of microservice instances in microservice.yaml, or by calling service center APIs. instance_description: properties: tags: tag_key: tag_value Consumers can specify provider instances' attributes to determine which instances to call. servicecomb: loadbalance: # Here the \"provider\" means the config items below only take effect on the service named \"provider\" # In cross-app invocation, the AppID should be prefixed, like \"AppIDOfProvider:provider\" provider: transactionControl: options: tags: tag_key: expected_tag_value The above configuration shows that only the instances of \"provider\" with the tag attribute tag_key:expected_tag_value are called. This rule needs to be configured separately for each service. Global rule for all services is not supported. This rule is enabled by default, it can be disabled by setting servicecomb.loadbalance.filter.instanceProperty.enabled to false. The instance attributes based routing policy is implemented in InstancePropertyDiscoveryFilter .","title":"Routing and forwarding by instance attributes"},{"location":"references-handlers/loadbalance/#routing-and-forwarding-by-instance-attributes-with-hierarchy-value","text":"This is a extension of the feature above. You can specify the properties of microservice instances in microservice.yaml with hierarchy value, which is separated by . symbol. instance_description: properties: KEY: a.b.c Consumer need to specify the key of instance which is used to match provider, the default key is environment servicecomb: loadbalance: filter: priorityInstanceProperty: key: KEY Assuming there is a consumer instance with property value a.b.c , the match priority of provider will be a.b.c > a.b > a > [empty] and the table shown below gives detail match priority. | consumer | match priority of provider| | :--- | :--- | |a.b.c|a.b.c>a.b>a>[empty]| |a.b|a.b>a>[empty]| |a|a>[empty]| |[empty]|[empty]| Note that [empty] is represent for the instances which is not set value of this property key This rule is NOT enabled by default, which can be enabled by setting servicecomb.loadbalance.filter.priorityInstanceProperty.enabled to true. The policy is implemented in PriorityInstancePropertyDiscoveryFilter .","title":"Routing and forwarding by instance attributes with hierarchy value"},{"location":"references-handlers/loadbalance/#instance-isolation","text":"Developers can configure instance-isolated parameters to temporarily drop access to the wrong instance, improving system reliability and performance. Below are the configuration items and default values: servicecomb: loadbalance: isolation: enabled: true errorThresholdPercentage: 0 enableRequestThreshold: 5 singleTestTime: 60000 continuousFailureThreshold: 5 The interval of isolation calculation is 1 minute. According to the above configuration, in 1 minute, if the total number of requests is greater than 5, and more than 2 consecutive errors occur, the instance is isolated. The default value of errorThresholdPercentage is 0, indicates that the rule is ommited. The item should be a integer less than 100, for example 20, then within 1 minutes, if the total number of request is greater than 5 and [1] error rate is greater than 20% or [2] more than 2 consecutive errors occur, is instance is isolated. After 60 seconds, the instance will be re-enabled and accessible if it matches the rules of load balancing policy. Notes: When error rate reaches the threshold, is instance is isolated and the error rate will be calculated again after the interval. Then with the successful accesses, the rate will decrease and become less than the threshold, then instance is available again. Since the rate is calculated by number of requests, if the total requests reaches the threshold and the error rate is much greater than its threshold, the instance would take a long time to recover. ServiceComb starts a thread in the background to detect the instance state, and checks the instance state every 10 seconds (if the instance is accessed within 10 seconds, it is not detected). If the detection fails, the error number is accumulated with 1. The count here also affects instance isolation. The default instance state detection mechanism is to send a telnet instruction, refer to the implementation of SimpleMicroserviceInstancePing. Users can overwrite the status detection mechanism with the following two steps: Implement the MicroserviceInstancePing interface Configure SPI: Add META-INF/services/org.apache.servicecomb.serviceregistry.consumer.MicroserviceInstancePing, the content is the full path of the implementation class Developers can configure different isolation policies for different microservices. Just add a service name to the configuration item, for example: servicecomb: loadbalance: myservice: isolation: enabled: true errorThresholdPercentage: 20 enableRequestThreshold: 5 singleTestTime: 10000 continuousFailureThreshold: 2 This rule is enabled by default and can be turned off by setting servicecomb.loadbalance.filter.isolation.enabled to false. Data center information isolation is implemented in IsolationDiscoveryFilter.","title":"Instance isolation"},{"location":"references-handlers/loadbalance/#configuring-route-rules","text":"Developers can specify load balancing policies through configuration items. servicecomb: loadbalance: strategy: name: RoundRobin # Support RoundRobin,Random,WeightedResponse,SessionStickiness Developers can configure policies for different microservices by adding a service name, for example: servicecomb: loadbalance: myservice: strategy: name: RoundRobin # Support RoundRobin,Random,WeightedResponse,SessionStickiness Each policy has some specific configuration items. SessionStickiness servicecomb: loadbalance: SessionStickinessRule: sessionTimeoutInSeconds: 30 # Client idle time, after the limit is exceeded, select the server behind successiveFailedTimes: 5 # The number of client failures will switch after the server is exceeded.","title":"Configuring route rules"},{"location":"references-handlers/loadbalance/#set-retry-strategy","text":"The load balancing module also supports the policy retry. servicecomb: loadbalance: retryEnabled: false retryOnNext: 0 retryOnSame: 0 Retry is not enabled by default. Developers can set different strategies for different services: servicecomb: loadbalance: myservice\uff1a retryEnabled: true retryOnNext: 1 retryOnSame: 0 retryOnNext indicates that after the failure, according to the load balancing policy, re-select an instance to retry (may choose the same instance), while retryOnSame means that the last failed instance is still used for retry.","title":"Set retry strategy"},{"location":"references-handlers/loadbalance/#customization","text":"The load balancing module provides various configurations that can support most application scenarios. It also provides flexible extension capabilities, including DiscoveryFilter, ServerListFilterExt, ExtensionsFactory (extension IRule, RetryHandler, etc.). The loadbalance module itself contains the implementation of each extension. The brief introduction of extending load balancing module is described below. Developers can download the ServiceComb source code to see the details. DiscoveryFilter Implement the DiscoveryFilter interface Configure SPI: Add META-INF/services/org.apache.servicecomb.serviceregistry.discovery.DiscoveryFilter file with the full path of the implementation class ServerListFilterExt Implement the ServerListFilterExt interface Configure SPI: Add META-INF/services/org.apache.servicecomb.loadbalance.ServerListFilterExt file, the content is the full pathof the implementation class Note: This instruction applies to version 1.0.0 and later. Earlier versions are extended in a different way. ExtensionsFactory Implement the ExtensionsFactory and publish it as a spring bean using @Component.","title":"Customization"},{"location":"references-handlers/publickey/","text":"public key authentication Scene Description Public key authentication is a simple and efficient authentication mechanism between microservices provided by ServiceComb. Its security is based on the trust between microservices and service centers, namely microservices and service centers. The authentication mechanism must be enabled first. Its basic process is as follows: When the microservice starts, generate a secret key pair and register the public key to the service center. The consumer signs the message with his or her private key before accessing the provider. The provider obtains the consumer public key from the service center and verifies the signed message. Public key authentication needs to be enabled for both consumers and providers. servicecomb: handler: chain: Consumer: default: auth-consumer Provider: default: auth-provider POM Dependency: Add dependencies in pom.xml: <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>handler-publickey-auth</artifactId> </dependency> Configuring black and white list Based on the public key authentication mechanism, ServiceComb provides a black and white list function. Through the black and white list, you can control which other services are allowed to be accessed by the microservice. Currently supported by configuring service attributes, the configuration items are as follows: servicecomb: publicKey: accessControl: black: list01: category: property ## property, fixed value propertyName: serviceName ## property name # property value matches expression. # only supports prefix match and postfix match and exactly match. #, e.g., hacker*, *hacker, hacker rule: hacker white: list02: category: property propertyName: serviceName rule: cust* The above rules are configured with blacklists, which do not allow microservice names to be accessed by hackers; whitelists allow access to services with microservice names named cust. ServiceComb provides [trust-sample] (https://github.com/apache/servicecomb-samples/tree/master/java-chassis-samples/trust-sample) to demonstrate the black and white list feature.","title":"Public key authentication"},{"location":"references-handlers/publickey/#public-key-authentication","text":"","title":"public key authentication"},{"location":"references-handlers/publickey/#scene-description","text":"Public key authentication is a simple and efficient authentication mechanism between microservices provided by ServiceComb. Its security is based on the trust between microservices and service centers, namely microservices and service centers. The authentication mechanism must be enabled first. Its basic process is as follows: When the microservice starts, generate a secret key pair and register the public key to the service center. The consumer signs the message with his or her private key before accessing the provider. The provider obtains the consumer public key from the service center and verifies the signed message. Public key authentication needs to be enabled for both consumers and providers. servicecomb: handler: chain: Consumer: default: auth-consumer Provider: default: auth-provider POM Dependency: Add dependencies in pom.xml: <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>handler-publickey-auth</artifactId> </dependency>","title":"Scene Description"},{"location":"references-handlers/publickey/#configuring-black-and-white-list","text":"Based on the public key authentication mechanism, ServiceComb provides a black and white list function. Through the black and white list, you can control which other services are allowed to be accessed by the microservice. Currently supported by configuring service attributes, the configuration items are as follows: servicecomb: publicKey: accessControl: black: list01: category: property ## property, fixed value propertyName: serviceName ## property name # property value matches expression. # only supports prefix match and postfix match and exactly match. #, e.g., hacker*, *hacker, hacker rule: hacker white: list02: category: property propertyName: serviceName rule: cust* The above rules are configured with blacklists, which do not allow microservice names to be accessed by hackers; whitelists allow access to services with microservice names named cust. ServiceComb provides [trust-sample] (https://github.com/apache/servicecomb-samples/tree/master/java-chassis-samples/trust-sample) to demonstrate the black and white list feature.","title":"Configuring black and white list"},{"location":"security/rsa/","text":"Scene Description Users can enable RSA authentication between services through simple configuration to ensure the security of the service interface. Detailed introduction [public key authentication] (../references-handlers/publickey.md) Consumer Configuration Add dependencies in pom.xml: <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>handler-publickey-auth</artifactId> </dependency> Added to the processing chain in microservice.yaml servicecomb: handler: chain: Consumer: default: auth-consumer Provider Configuration Add dependencies in pom.xml: <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>handler-publickey-auth</artifactId> </dependency> Added to the processing chain in microservice.yaml servicecomb: handler: chain: Provider: default: auth-provider","title":"Using RSA certification"},{"location":"security/rsa/#scene-description","text":"Users can enable RSA authentication between services through simple configuration to ensure the security of the service interface. Detailed introduction [public key authentication] (../references-handlers/publickey.md)","title":"Scene Description"},{"location":"security/rsa/#consumer-configuration","text":"Add dependencies in pom.xml: <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>handler-publickey-auth</artifactId> </dependency> Added to the processing chain in microservice.yaml servicecomb: handler: chain: Consumer: default: auth-consumer","title":"Consumer Configuration"},{"location":"security/rsa/#provider-configuration","text":"Add dependencies in pom.xml: <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>handler-publickey-auth</artifactId> </dependency> Added to the processing chain in microservice.yaml servicecomb: handler: chain: Provider: default: auth-provider","title":"Provider Configuration"},{"location":"security/tls/","text":"Scene Description Users can enable TLS communication through simple configuration to ensure data transmission security. External Service Communication Configuration The configuration related to external service communication is written in the microservice.yaml file. Service Center, Configuration Center TLS communication configuration The connection between the microservices and the service center and the configuration center can be enabled by changing http to https. The configuration example is as follows: yaml servicecomb: service: registry: address: https://127.0.0.1:30100 config: client: serverUri: https://127.0.0.1:30103 Service provider enables TLS communication When the service provider configures the service listening address, it can open TLS communication by appending ?sslEnabled=true to the address. The example is as follows: yaml servicecomb: rest: address: 0.0.0.0:8080?sslEnabled=true highway: address: 0.0.0.0:7070?sslEnabled=true Certificate Configuration The certificate configuration item is written in the microservice.yaml file. It supports the unified development of certificates. It can also add tags for finer-grained configuration. The tag configuration overrides the global configuration. The configuration format is as follows: ssl.[tag].[property] The common tags are as follows: Project tag Service Center sc.consumer Configuration Center cc.consumer Kanban Center mc.consumer Rest server rest.provider Highway Server highway.provider Rest client rest.consumer Highway Client highway.consumer auth client apiserver.consumer Generally, there is no need to configure tags. The normal situation is divided into three categories: 1. Connecting internal services 2. As a server 3. As a client, if the certificates required by these three types are inconsistent, then you need to use tags to distinguish The certificate configuration items are shown in Table 1. Certificate Configuration Item Description Table. Table 1 Certificate Configuration Item Description Table Configuration Item Default Value Range of Value Required Meaning Caution Ssl.engine jdk - No ssl protocol, provide jdk/openssl options default jdk ssl.protocols TLSv1.2 - No Protocol List separated by comma ssl.ciphers TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH _AES_128_GCM_SHA256 - No List of laws separated by comma ssl.authPeer false - No Whether to authenticate the peer - ssl.checkCN.host false - No Check whether the CN of the certificate is checked. This configuration item is valid only on the Consumer side and is valid using the http protocol. That is, the Consusser side uses the rest channel. Invalid for Provider, highway, etc. The purpose of checking CN is to prevent the server from being phishing, refer to Standard definition: https://tools.ietf.org/html/rfc2818. ssl.trustStore trust.jks - No Trust certificate file - ssl.trustStoreType JKS - No Trust Certificate Type - ssl.trustStoreValue - - No Trust Certificate Password - ssl.keyStore server.p12 - No Identity Certificate File - ssl.keyStoreType PKCS12 - No Identity Certificate Type - ssl.keyStoreValue - - No Identity Certificate Password - ssl.crl revoke.crl - No Revoked Certificate File - ssl.sslCustomClass - org.apache.servicecomb.foundation.ssl.SSLCustom implementation class No SSLCustom class implementation for developers to convert passwords, file paths, etc. - Description : The default protocol algorithm is a high-intensity encryption algorithm. The JDK needs to install the corresponding policy file. Reference: http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html . You can use a non-high-intensity algorithm in your profile configuration. Microservice consumers, can specify certificates for different providers (current certificates are issued according to HOST, different providers use a certificate storage medium, this medium is also used by the microservice access service center and configuration center ). Sample Code An example of a configuration for enabling TLS communication in the microservice.yaml file is as follows: servicecomb: service: registry: address: https://127.0.0.1:30100 config: client: serverUri: https://127.0.0.1:30103 rest: address: 0.0.0.0:8080?sslEnabled=true highway: address: 0.0.0.0:7070?sslEnabled=true #########SSL options ssl.protocols: TLSv1.2 ssl.authPeer: true ssl.checkCN.host: true #########certificates config ssl.trustStore: trust.jks ssl.trustStoreType: JKS ssl.trustStoreValue: Changeme_123 ssl.keyStore: server.p12 ssl.keyStoreType: PKCS12 ssl.keyStoreValue: Changeme_123 ssl.crl: revoke.crl ssl.sslCustomClass: org.apache.servicecomb.demo.DemoSSLCustom","title":"Using TLS"},{"location":"security/tls/#scene-description","text":"Users can enable TLS communication through simple configuration to ensure data transmission security.","title":"Scene Description"},{"location":"security/tls/#external-service-communication-configuration","text":"The configuration related to external service communication is written in the microservice.yaml file. Service Center, Configuration Center TLS communication configuration The connection between the microservices and the service center and the configuration center can be enabled by changing http to https. The configuration example is as follows: yaml servicecomb: service: registry: address: https://127.0.0.1:30100 config: client: serverUri: https://127.0.0.1:30103 Service provider enables TLS communication When the service provider configures the service listening address, it can open TLS communication by appending ?sslEnabled=true to the address. The example is as follows: yaml servicecomb: rest: address: 0.0.0.0:8080?sslEnabled=true highway: address: 0.0.0.0:7070?sslEnabled=true","title":"External Service Communication Configuration"},{"location":"security/tls/#certificate-configuration","text":"The certificate configuration item is written in the microservice.yaml file. It supports the unified development of certificates. It can also add tags for finer-grained configuration. The tag configuration overrides the global configuration. The configuration format is as follows: ssl.[tag].[property] The common tags are as follows: Project tag Service Center sc.consumer Configuration Center cc.consumer Kanban Center mc.consumer Rest server rest.provider Highway Server highway.provider Rest client rest.consumer Highway Client highway.consumer auth client apiserver.consumer Generally, there is no need to configure tags. The normal situation is divided into three categories: 1. Connecting internal services 2. As a server 3. As a client, if the certificates required by these three types are inconsistent, then you need to use tags to distinguish The certificate configuration items are shown in Table 1. Certificate Configuration Item Description Table. Table 1 Certificate Configuration Item Description Table Configuration Item Default Value Range of Value Required Meaning Caution Ssl.engine jdk - No ssl protocol, provide jdk/openssl options default jdk ssl.protocols TLSv1.2 - No Protocol List separated by comma ssl.ciphers TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH _AES_128_GCM_SHA256 - No List of laws separated by comma ssl.authPeer false - No Whether to authenticate the peer - ssl.checkCN.host false - No Check whether the CN of the certificate is checked. This configuration item is valid only on the Consumer side and is valid using the http protocol. That is, the Consusser side uses the rest channel. Invalid for Provider, highway, etc. The purpose of checking CN is to prevent the server from being phishing, refer to Standard definition: https://tools.ietf.org/html/rfc2818. ssl.trustStore trust.jks - No Trust certificate file - ssl.trustStoreType JKS - No Trust Certificate Type - ssl.trustStoreValue - - No Trust Certificate Password - ssl.keyStore server.p12 - No Identity Certificate File - ssl.keyStoreType PKCS12 - No Identity Certificate Type - ssl.keyStoreValue - - No Identity Certificate Password - ssl.crl revoke.crl - No Revoked Certificate File - ssl.sslCustomClass - org.apache.servicecomb.foundation.ssl.SSLCustom implementation class No SSLCustom class implementation for developers to convert passwords, file paths, etc. - Description : The default protocol algorithm is a high-intensity encryption algorithm. The JDK needs to install the corresponding policy file. Reference: http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html . You can use a non-high-intensity algorithm in your profile configuration. Microservice consumers, can specify certificates for different providers (current certificates are issued according to HOST, different providers use a certificate storage medium, this medium is also used by the microservice access service center and configuration center ).","title":"Certificate Configuration"},{"location":"security/tls/#sample-code","text":"An example of a configuration for enabling TLS communication in the microservice.yaml file is as follows: servicecomb: service: registry: address: https://127.0.0.1:30100 config: client: serverUri: https://127.0.0.1:30103 rest: address: 0.0.0.0:8080?sslEnabled=true highway: address: 0.0.0.0:7070?sslEnabled=true #########SSL options ssl.protocols: TLSv1.2 ssl.authPeer: true ssl.checkCN.host: true #########certificates config ssl.trustStore: trust.jks ssl.trustStoreType: JKS ssl.trustStoreValue: Changeme_123 ssl.keyStore: server.p12 ssl.keyStoreType: PKCS12 ssl.keyStoreValue: Changeme_123 ssl.crl: revoke.crl ssl.sslCustomClass: org.apache.servicecomb.demo.DemoSSLCustom","title":"Sample Code"},{"location":"security/tls/shi-yong-rsa-ren-zheng/","text":"","title":"Shi yong rsa ren zheng"},{"location":"start/architecture/","text":"Java Chassis Architecture Basic Framework Purpose 1.To decouple the programming model and communication model, so that a programming model can be combined with any communication models as needed. Application developers only need to focus on APIs during development and can flexibly switch communication models during deployment. Services can also be switched over to a legacy system. The developers simply need to modify the configuration file(or annotation) released by the service. Currently, applications can be developed in Spring MVC, JAX-RS, or transparent RPC mode. Built-in API-first support. Through contract standardize micro-service development, realizing cross-language communication, and supporting software toolchain (contract generation code, code generation contract, etc.) development, to construct a complete development ecology. 3.To define common microservice running model, encapsulating fault tolerance methods to process which from service discovery to interaction process of microservices, The running model can be customized or extended. Modules Type artifact id Available or NOT Function Programming model provider-pojo Yes Provides the RPC development mode. Programming model provider-jaxrs Yes Provides the JAX-RS development mode. Programming model provider-springmvc Yes Provides the Spring MVC development mode. Communication on model transport-rest-vertx Yes A development framework running over HTTP, it does not depend on Web containers. Applications are packaged as executable .jar files. Communication on model transport-rest-servlet Yes A development framework running on Web container. Applications are packaged as WAR files. Communication on model transport-highway Yes Provides high-performance private communication protocols for Java communication. Running model handler-loadbalance Yes A load balancing module that provides various routing policies and configurations. It is usually used on the Consumer side. Running model handler-bizkeeper Yes Provides service governance functions, such as isolation, fallbreak, and fault tolerance. Running model handler-tracing Yes Invoke tracking chain module, Monitor system integration, Output data of buried point","title":"Architecture"},{"location":"start/architecture/#java-chassis-architecture","text":"","title":"Java Chassis Architecture"},{"location":"start/architecture/#basic-framework","text":"","title":"Basic Framework"},{"location":"start/architecture/#purpose","text":"1.To decouple the programming model and communication model, so that a programming model can be combined with any communication models as needed. Application developers only need to focus on APIs during development and can flexibly switch communication models during deployment. Services can also be switched over to a legacy system. The developers simply need to modify the configuration file(or annotation) released by the service. Currently, applications can be developed in Spring MVC, JAX-RS, or transparent RPC mode. Built-in API-first support. Through contract standardize micro-service development, realizing cross-language communication, and supporting software toolchain (contract generation code, code generation contract, etc.) development, to construct a complete development ecology. 3.To define common microservice running model, encapsulating fault tolerance methods to process which from service discovery to interaction process of microservices, The running model can be customized or extended.","title":"Purpose"},{"location":"start/architecture/#modules","text":"Type artifact id Available or NOT Function Programming model provider-pojo Yes Provides the RPC development mode. Programming model provider-jaxrs Yes Provides the JAX-RS development mode. Programming model provider-springmvc Yes Provides the Spring MVC development mode. Communication on model transport-rest-vertx Yes A development framework running over HTTP, it does not depend on Web containers. Applications are packaged as executable .jar files. Communication on model transport-rest-servlet Yes A development framework running on Web container. Applications are packaged as WAR files. Communication on model transport-highway Yes Provides high-performance private communication protocols for Java communication. Running model handler-loadbalance Yes A load balancing module that provides various routing policies and configurations. It is usually used on the Consumer side. Running model handler-bizkeeper Yes Provides service governance functions, such as isolation, fallbreak, and fault tolerance. Running model handler-tracing Yes Invoke tracking chain module, Monitor system integration, Output data of buried point","title":"Modules"},{"location":"start/deployment-on-cloud/","text":"\u672c\u7ae0\u8282\u4e3b\u8981\u63cf\u8ff0\u5fae\u670d\u52a1\u53d1\u5e03\u5230\u534e\u4e3a\u516c\u6709\u4e91\u4e0a\u3002\u4e0a\u4e91\u914d\u7f6e\u7684\u57fa\u672c\u539f\u5219\u662f\uff1a\u53ea\u9700\u8981\u5bf9microservice.yaml\u8fdb\u884c\u9002\u5f53\u7684\u914d\u7f6e\uff0c\u4ee5\u53ca\u5728pom\u4e2d\u6dfb\u52a0\u989d\u5916\u7684\u4f9d\u8d56\uff0c\u5c31\u53ef\u4ee5\u4f7f\u7528\u76f8\u5173\u7684\u529f\u80fd\u3002 \u4e00\u952e\u5f0f\u914d\u7f6e \u516c\u6709\u4e91\u7248\u672c\u63d0\u4f9b\u4e86\u4e00\u952e\u5f0f\u7b80\u5316\u914d\u7f6e\u7684\u65b9\u5f0f\uff0c\u8ba9\u57fa\u4e8e\u5f00\u6e90\u7248\u672c\u5f00\u53d1\u7684\u5e94\u7528\u5feb\u901f\u5207\u6362\u4e3a\u4e91\u4e0a\u5e94\u7528\uff0c\u76f4\u63a5\u4f7f\u7528\u516c\u6709\u4e91\u63d0\u4f9b\u7684\u7070\u5ea6\u53d1\u5e03\u3001\u670d\u52a1\u6cbb\u7406\u7b49\u529f\u80fd\u3002 \u589e\u52a0\u4f9d\u8d56\u5173\u7cfb(pom.xml) <dependency> <groupId>com.huawei.paas.cse</groupId> <artifactId>cse-solution-service-engine</artifactId> </dependency> \u5f00\u53d1\u8005\u53ea\u9700\u8981\u914d\u7f6e\u5bf9cse-solution-service-engine\u4f9d\u8d56\uff0c\u5c31\u5b8c\u6210\u4e86\u516c\u6709\u4e91\u7684\u6240\u6709\u914d\u7f6e\u3002\u8fd9\u4e2a\u4f9d\u8d56\u5173\u7cfb\u4e3b\u8981\u7ed9\u5f00\u53d1\u8005\u505a\u4e86\u5982\u4e0b\u4e8b\u60c5\uff1a \u5f15\u5165\u76f8\u5173\u4f9d\u8d56\u7684\u7ec4\u4ef6 \u589e\u52a0\u9ed8\u8ba4\u914d\u7f6e\u9879\u3002\u9ed8\u8ba4\u914d\u7f6e\u5305\u542b\u4e86\u5904\u7406\u94fe\u3001\u8d1f\u8f7d\u5747\u8861\u7b56\u7565\u7b49\u3002 \u53ef\u4ee5\u901a\u8fc7\u67e5\u770bpom\u5185\u5bb9\uff0c\u4ee5\u53ca\u8fd9\u4e2ajar\u5305\u91cc\u9762\u7684microservice.yaml\u6587\u4ef6\u67e5\u770b\u5f15\u5165\u7684\u7ec4\u4ef6\u548c\u589e\u52a0\u7684\u914d\u7f6e\u9879\u3002\u5728\u4e0b\u9762\u7684\u7ae0\u8282\u4e2d\uff0c\u8be6\u7ec6\u89e3\u91ca\u4e0a\u4e91\u589e\u52a0\u7684\u7ec4\u4ef6\u4ee5\u53ca\u4ed6\u4eec\u7684\u4f5c\u7528\uff0c\u8ba9\u5f00\u53d1\u8005\u66f4\u52a0\u6df1\u5165\u7684\u4e86\u89e3\u5404\u79cd\u6280\u672f\u7ec6\u8282\u3002 \u8fde\u63a5\u670d\u52a1\u4e2d\u5fc3 \u529f\u80fd\u63cf\u8ff0 \u670d\u52a1\u4e2d\u5fc3\u5b9e\u73b0\u6ce8\u518c\u548c\u53d1\u73b0\uff0c\u5728FusionStage/ServiceStage\u67e5\u770b\u5fae\u670d\u52a1\u76ee\u5f55\uff0c\u90fd\u9700\u8981\u5fae\u670d\u52a1\u8fde\u63a5\u4e0a\u670d\u52a1\u4e2d\u5fc3\u3002 \u914d\u7f6e\u53c2\u8003 \u589e\u52a0\u4f9d\u8d56\u5173\u7cfb(pom.xml) \u5982\u679c\u8fde\u63a5\u670d\u52a1\u4e2d\u5fc3\u4f7f\u7528https\u534f\u8bae/AK/SK\u8ba4\u8bc1\uff0c\u8be5jar\u4f9d\u8d56\u5fc5\u9009\u3002\u5982\u679c\u662fhttp\u534f\u8bae\uff0c\u5e76\u4e0d\u5305\u542btoken\u9a8c\u8bc1\uff0c\u5219\u65e0\u9700\u5f15\u5165\u3002 <dependency> <groupId>com.huawei.paas.cse</groupId> <artifactId>foundation-auth</artifactId> </dependency> \u914d\u7f6e\u9879(microservice.yaml\uff09 servicecomb: service: registry: address: https://servicecomb.cn-north-1.myhwclouds.com:443 #\u6839\u636e\u5b9e\u9645\u5730\u5740\u914d\u7f6e\u670d\u52a1\u4e2d\u5fc3\u5730\u5740 \u8be5\u914d\u7f6e\u9879\u914d\u7f6e\u4e86\u670d\u52a1\u4e2d\u5fc3\u7684\u5730\u5740\u3002\u5176\u4e2d\uff0caddress\u53ef\u4ee5\u5728\u516c\u6709\u4e91\u201c\u5de5\u5177\u548c\u6848\u4f8b\u201d\u76ee\u5f55\u4e0b\u67e5\u5230\u5bf9\u5e94\u7684\u670d\u52a1\u4e2d\u5fc3\u5730\u5740\uff0c\u4fee\u6539\u534f\u8bae\uff08http/https\uff09\u3001\u4e3b\u673a\u540d\uff08\u53ef\u80fd\u4f7f\u7528\u57df\u540d\uff09\u548c\u7aef\u53e3\u53f7\u3002 \u8fde\u63a5\u914d\u7f6e\u4e2d\u5fc3 \u529f\u80fd\u63cf\u8ff0 \u914d\u7f6e\u4e2d\u5fc3\u5b9e\u73b0\u914d\u7f6e\u4e0b\u53d1\uff0c\u8fde\u63a5\u914d\u7f6e\u4e2d\u5fc3\u662f\u4f7f\u7528\u6cbb\u7406\u3001\u7070\u5ea6\u53d1\u5e03\u7b49\u529f\u80fd\u7684\u524d\u53f0\u3002 \u914d\u7f6e\u53c2\u8003 \u589e\u52a0\u4f9d\u8d56\u5173\u7cfb(pom.xml) \u5982\u679c\u8fde\u63a5\u914d\u7f6e\u4e2d\u5fc3\u4f7f\u7528https\u534f\u8bae/AK/SK\u8ba4\u8bc1\uff0c\u8be5jar\u4f9d\u8d56\u5fc5\u9009\u3002\u5982\u679c\u662fhttp\u534f\u8bae\uff0c\u5e76\u4e0d\u5305\u542btoken\u9a8c\u8bc1\uff0c\u5219\u65e0\u9700\u5f15\u5165\u3002 <dependency> <groupId>com.huawei.paas.cse</groupId> <artifactId>foundation-auth</artifactId> </dependency> \u8fde\u63a5\u914d\u7f6e\u4e2d\u5fc3\u8be5jar\u5fc5\u9009 <dependency> <groupId>com.huawei.paas.cse</groupId> <artifactId>foundation-config-cc</artifactId> </dependency> \u542f\u7528\u914d\u7f6e(microservice.yaml\uff09 servicecomb: config: client: serverUri: https://servicecomb.cn-north-1.myhwclouds.com:443 \u8be5\u914d\u7f6e\u9879\u914d\u7f6e\u4e86\u914d\u7f6e\u4e2d\u5fc3\u7684\u5730\u5740\u3002\u5176\u4e2d\uff0caddress\u53ef\u4ee5\u5728\u516c\u6709\u4e91\u201c\u5de5\u5177\u548c\u6848\u4f8b\u201d\u76ee\u5f55\u4e0b\u67e5\u5230\u5bf9\u5e94\u7684\u914d\u7f6e\u4e2d\u5fc3\u5730\u5740\uff0c\u4fee\u6539\u534f\u8bae\uff08http/https\uff09\u3001\u4e3b\u673a\u540d\uff08\u53ef\u80fd\u4f7f\u7528\u57df\u540d\uff09\u548c\u7aef\u53e3\u53f7\u3002 \u4f7f\u7528\u670d\u52a1\u6cbb\u7406 \u529f\u80fd\u63cf\u8ff0 \u670d\u52a1\u6cbb\u7406\u4e3b\u8981\u6d89\u53ca\u201c\u9694\u79bb\u201d\u3001\u201c\u7194\u65ad\u201d\u3001\u201c\u5bb9\u9519\u201d\u3001\u201c\u9650\u6d41\u201d\u3001\u201c\u8d1f\u8f7d\u5747\u8861\u201d\u7b49\u3002 \u914d\u7f6e\u53c2\u8003 \u914d\u7f6e\u9879(microservice.yaml\uff09 \u9700\u8981\u589e\u52a0\u4e0b\u9762\u6cbb\u7406\u76f8\u5173\u7684handler\uff0c\u624d\u80fd\u5728\u4ece\u914d\u7f6e\u4e2d\u5fc3\u5b9e\u65f6\u83b7\u53d6\u6cbb\u7406\u6570\u636e\u3002 servicecomb: handler: chain: Provider: default: bizkeeper-provider,qps-flowcontrol-provider Consumer: default: bizkeeper-consumer,loadbalance,qps-flowcontrol-consumer \u4f7f\u7528\u6545\u969c\u6ce8\u5165 \u529f\u80fd\u63cf\u8ff0 \u6545\u969c\u6ce8\u5165\u4e3b\u8981\u63d0\u4f9b\u4e86\u5ef6\u65f6\u3001\u9519\u8bef\u4e24\u79cd\u7c7b\u578b\u6545\u969c\u3002 \u914d\u7f6e\u53c2\u8003 \u914d\u7f6e\u9879(microservice.yaml\uff09 \u9700\u8981\u589e\u52a0\u4e0b\u9762\u6cbb\u7406\u76f8\u5173\u7684handler\u3002 servicecomb: handler: chain: Consumer: default: loadbalance,fault-injection-consumer \u4f7f\u7528\u7070\u5ea6\u53d1\u5e03 \u529f\u80fd\u63cf\u8ff0 \u8be5\u529f\u80fd\u5bf9\u5e94\u4e8e\u5fae\u670d\u52a1\u76ee\u5f55\u7070\u5ea6\u53d1\u5e03\u529f\u80fd\u3002\u7ba1\u7406\u5458\u53ef\u4ee5\u901a\u8fc7\u4e0b\u53d1\u89c4\u5219\uff0c\u5bf9\u670d\u52a1\u8fdb\u884c\u7070\u5ea6\u53d1\u5e03\u7ba1\u7406\u3002 \u914d\u7f6e\u53c2\u8003 \u589e\u52a0\u4f9d\u8d56\u5173\u7cfb(pom.xml) \u5f15\u5165\u5fc5\u8981\u7684jar\u5305\u3002 <dependency> <groupId>com.huawei.paas.cse</groupId> <artifactId>cse-handler-cloud-extension</artifactId> </dependency> \u5728Consumer\u7aef\u914d\u7f6e\u8d1f\u8f7d\u5747\u8861(microservice.yaml\uff09 \u5728\u8d1f\u8f7d\u5747\u8861\u6a21\u5757\u542f\u7528\u4e86\u7070\u5ea6\u53d1\u5e03\u7684filter\u3002 servicecomb: loadbalance: serverListFilters: darklaunch serverListFilter: darklaunch: className: com.huawei.paas.darklaunch.DarklaunchServerListFilter \u4f7f\u7528\u8c03\u7528\u94fe \u529f\u80fd\u63cf\u8ff0 \u534e\u4e3a\u4e91\u63d0\u4f9b\u4e86\u4e1a\u52a1\u65e0\u4fb5\u5165\u7684\u57cb\u70b9\u529f\u80fdAPM\u3002\u53ea\u9700\u8981\u901a\u8fc7\u534e\u4e3a\u4e91\u90e8\u7f72\u5bb9\u5668\u5e94\u7528\uff0c\u5e76\u9009\u62e9\u542f\u7528\u8c03\u7528\u94fe\u76d1\u63a7\u529f\u80fd\uff0c\u5373\u53ef\u4f7f\u7528\u8c03\u7528\u94fe\u670d\u52a1\u3002 \u5fae\u670d\u52a1\u8fd0\u884c\u6570\u636e\u4e0a\u62a5 \u529f\u80fd\u63cf\u8ff0 \u5fae\u670d\u52a1\u53ef\u4ee5\u5c06\u81ea\u5df1\u7684\u8fd0\u884c\u6570\u636e\u4e0a\u62a5\u7ed9Dashboard\u670d\u52a1\uff0c\u5728\u516c\u6709\u4e91\u4e0a\u67e5\u770b\u4eea\u8868\u76d8\u6570\u636e\u3001\u5206\u5e03\u5f0f\u4e8b\u52a1\u6570\u636e\u7b49\u3002\u8be5\u7ae0\u8282\u662f\u63cf\u8ff0\u5982\u4f55\u542f\u7528\u5fae\u670d\u52a1\u6570\u636e\u4e0a\u62a5\u529f\u80fd\u3002 \u914d\u7f6e\u53c2\u8003 \u589e\u52a0\u4f9d\u8d56\u5173\u7cfb(pom.xml) \u5f15\u5165\u5fc5\u8981\u7684jar\u5305\u3002 <dependency> \u3000\u3000<groupId>com.huawei.paas.cse</groupId> \u3000\u3000<artifactId>cse-handler-cloud-extension</artifactId> </dependency> \u914d\u7f6ehandler \u4eea\u8868\u76d8\u6570\u636e\u4f9d\u8d56\u4e8e\u4e24\u4e2ahandler\uff0c\u4e00\u4e2abizkeeper-provider\uff08\u5ba2\u6237\u7aef\u4e3abizkeeper-consumer\uff09\uff0c\u4e00\u4e2aperf-stats\uff0c\u6240\u4ee5\u5bf9\u5e94\u7684pom\u4f9d\u8d56\u9700\u8981\u5148\u5f15\u5165\u3002 servicecomb: handler: chain: Provider: default: bizkeeper-provider,perf-stats,tracing-provider,sla-provider Consumer: default: bizkeeper-consumer,loadbalance,perf-stats,tracing-consumer,sla-consumer \u914d\u7f6e\u4e0a\u62a5monitor\u5730\u5740 TenantLB_ADDRESS\u4e3a\u5171\u6709\u4e91\u79df\u6237\u7ba1\u7406\u9762\u63a5\u5165\u5730\u5740\uff0c\u9ed8\u8ba4\u662f100.125.1.34\u3002 servicecomb: service: registry: address: https://${TenantLB_ADDRESS}:30100 monitor: client: serverUri: https://${TenantLB_ADDRESS}:30109 \u5206\u5e03\u5f0f\u4e8b\u52a1: TCC \u529f\u80fd\u63cf\u8ff0 \u4e3b\u8981\u5b9e\u73b0\u57fa\u4e8eTCC\u534f\u8bae\u7684\u5206\u5e03\u5f0f\u670d\u52a1\u95f4\u7684\u6700\u7ec8\u4e00\u81f4\u6027\u65b9\u6848\uff0c\u4fdd\u969c\u4e00\u822c\u573a\u666f\u4e0b\u7684\u5e94\u7528\u4e00\u81f4\u6027\u9700\u6c42\uff0c\u5e76\u53ef\u4ee5\u5728FusionStage/ServiceStage\u5206\u5e03\u5f0f\u4e8b\u52a1\u754c\u9762\u67e5\u770b\u4e8b\u52a1\u8be6\u7ec6\u4fe1\u606f\u3002 \u914d\u7f6e\u53c2\u8003 \u589e\u52a0\u4f9d\u8d56\u5173\u7cfb(pom.xml) \u5f15\u5165\u5fc5\u8981\u7684jar\u5305 <dependency> \u3000\u3000<groupId>com.huawei.paas.cse</groupId> \u3000\u3000<artifactId>cse-handler-tcc</artifactId> </dependency> \u914d\u7f6e\u9879\u53c2\u8003 \u9700\u8981\u589e\u52a0\u4e0b\u9762\u4e8b\u52a1\u76f8\u5173\u7684handler\uff0c\u624d\u80fd\u5728\u4ece\u914d\u7f6e\u4e2d\u5fc3\u5b9e\u65f6\u83b7\u53d6\u6cbb\u7406\u6570\u636e\u3002 servicecomb: handler: chain: Provider: default: tcc-client,bizkeeper-provider Consumer: default: tcc-server,bizkeeper-consumer,loadbalance","title":"Deployment on cloud"},{"location":"start/deployment-on-cloud/#_1","text":"\u516c\u6709\u4e91\u7248\u672c\u63d0\u4f9b\u4e86\u4e00\u952e\u5f0f\u7b80\u5316\u914d\u7f6e\u7684\u65b9\u5f0f\uff0c\u8ba9\u57fa\u4e8e\u5f00\u6e90\u7248\u672c\u5f00\u53d1\u7684\u5e94\u7528\u5feb\u901f\u5207\u6362\u4e3a\u4e91\u4e0a\u5e94\u7528\uff0c\u76f4\u63a5\u4f7f\u7528\u516c\u6709\u4e91\u63d0\u4f9b\u7684\u7070\u5ea6\u53d1\u5e03\u3001\u670d\u52a1\u6cbb\u7406\u7b49\u529f\u80fd\u3002 \u589e\u52a0\u4f9d\u8d56\u5173\u7cfb(pom.xml) <dependency> <groupId>com.huawei.paas.cse</groupId> <artifactId>cse-solution-service-engine</artifactId> </dependency> \u5f00\u53d1\u8005\u53ea\u9700\u8981\u914d\u7f6e\u5bf9cse-solution-service-engine\u4f9d\u8d56\uff0c\u5c31\u5b8c\u6210\u4e86\u516c\u6709\u4e91\u7684\u6240\u6709\u914d\u7f6e\u3002\u8fd9\u4e2a\u4f9d\u8d56\u5173\u7cfb\u4e3b\u8981\u7ed9\u5f00\u53d1\u8005\u505a\u4e86\u5982\u4e0b\u4e8b\u60c5\uff1a \u5f15\u5165\u76f8\u5173\u4f9d\u8d56\u7684\u7ec4\u4ef6 \u589e\u52a0\u9ed8\u8ba4\u914d\u7f6e\u9879\u3002\u9ed8\u8ba4\u914d\u7f6e\u5305\u542b\u4e86\u5904\u7406\u94fe\u3001\u8d1f\u8f7d\u5747\u8861\u7b56\u7565\u7b49\u3002 \u53ef\u4ee5\u901a\u8fc7\u67e5\u770bpom\u5185\u5bb9\uff0c\u4ee5\u53ca\u8fd9\u4e2ajar\u5305\u91cc\u9762\u7684microservice.yaml\u6587\u4ef6\u67e5\u770b\u5f15\u5165\u7684\u7ec4\u4ef6\u548c\u589e\u52a0\u7684\u914d\u7f6e\u9879\u3002\u5728\u4e0b\u9762\u7684\u7ae0\u8282\u4e2d\uff0c\u8be6\u7ec6\u89e3\u91ca\u4e0a\u4e91\u589e\u52a0\u7684\u7ec4\u4ef6\u4ee5\u53ca\u4ed6\u4eec\u7684\u4f5c\u7528\uff0c\u8ba9\u5f00\u53d1\u8005\u66f4\u52a0\u6df1\u5165\u7684\u4e86\u89e3\u5404\u79cd\u6280\u672f\u7ec6\u8282\u3002","title":"\u4e00\u952e\u5f0f\u914d\u7f6e"},{"location":"start/deployment-on-cloud/#_2","text":"","title":"\u8fde\u63a5\u670d\u52a1\u4e2d\u5fc3"},{"location":"start/deployment-on-cloud/#_3","text":"\u670d\u52a1\u4e2d\u5fc3\u5b9e\u73b0\u6ce8\u518c\u548c\u53d1\u73b0\uff0c\u5728FusionStage/ServiceStage\u67e5\u770b\u5fae\u670d\u52a1\u76ee\u5f55\uff0c\u90fd\u9700\u8981\u5fae\u670d\u52a1\u8fde\u63a5\u4e0a\u670d\u52a1\u4e2d\u5fc3\u3002","title":"\u529f\u80fd\u63cf\u8ff0"},{"location":"start/deployment-on-cloud/#_4","text":"\u589e\u52a0\u4f9d\u8d56\u5173\u7cfb(pom.xml) \u5982\u679c\u8fde\u63a5\u670d\u52a1\u4e2d\u5fc3\u4f7f\u7528https\u534f\u8bae/AK/SK\u8ba4\u8bc1\uff0c\u8be5jar\u4f9d\u8d56\u5fc5\u9009\u3002\u5982\u679c\u662fhttp\u534f\u8bae\uff0c\u5e76\u4e0d\u5305\u542btoken\u9a8c\u8bc1\uff0c\u5219\u65e0\u9700\u5f15\u5165\u3002 <dependency> <groupId>com.huawei.paas.cse</groupId> <artifactId>foundation-auth</artifactId> </dependency> \u914d\u7f6e\u9879(microservice.yaml\uff09 servicecomb: service: registry: address: https://servicecomb.cn-north-1.myhwclouds.com:443 #\u6839\u636e\u5b9e\u9645\u5730\u5740\u914d\u7f6e\u670d\u52a1\u4e2d\u5fc3\u5730\u5740 \u8be5\u914d\u7f6e\u9879\u914d\u7f6e\u4e86\u670d\u52a1\u4e2d\u5fc3\u7684\u5730\u5740\u3002\u5176\u4e2d\uff0caddress\u53ef\u4ee5\u5728\u516c\u6709\u4e91\u201c\u5de5\u5177\u548c\u6848\u4f8b\u201d\u76ee\u5f55\u4e0b\u67e5\u5230\u5bf9\u5e94\u7684\u670d\u52a1\u4e2d\u5fc3\u5730\u5740\uff0c\u4fee\u6539\u534f\u8bae\uff08http/https\uff09\u3001\u4e3b\u673a\u540d\uff08\u53ef\u80fd\u4f7f\u7528\u57df\u540d\uff09\u548c\u7aef\u53e3\u53f7\u3002","title":"\u914d\u7f6e\u53c2\u8003"},{"location":"start/deployment-on-cloud/#_5","text":"","title":"\u8fde\u63a5\u914d\u7f6e\u4e2d\u5fc3"},{"location":"start/deployment-on-cloud/#_6","text":"\u914d\u7f6e\u4e2d\u5fc3\u5b9e\u73b0\u914d\u7f6e\u4e0b\u53d1\uff0c\u8fde\u63a5\u914d\u7f6e\u4e2d\u5fc3\u662f\u4f7f\u7528\u6cbb\u7406\u3001\u7070\u5ea6\u53d1\u5e03\u7b49\u529f\u80fd\u7684\u524d\u53f0\u3002","title":"\u529f\u80fd\u63cf\u8ff0"},{"location":"start/deployment-on-cloud/#_7","text":"\u589e\u52a0\u4f9d\u8d56\u5173\u7cfb(pom.xml) \u5982\u679c\u8fde\u63a5\u914d\u7f6e\u4e2d\u5fc3\u4f7f\u7528https\u534f\u8bae/AK/SK\u8ba4\u8bc1\uff0c\u8be5jar\u4f9d\u8d56\u5fc5\u9009\u3002\u5982\u679c\u662fhttp\u534f\u8bae\uff0c\u5e76\u4e0d\u5305\u542btoken\u9a8c\u8bc1\uff0c\u5219\u65e0\u9700\u5f15\u5165\u3002 <dependency> <groupId>com.huawei.paas.cse</groupId> <artifactId>foundation-auth</artifactId> </dependency> \u8fde\u63a5\u914d\u7f6e\u4e2d\u5fc3\u8be5jar\u5fc5\u9009 <dependency> <groupId>com.huawei.paas.cse</groupId> <artifactId>foundation-config-cc</artifactId> </dependency> \u542f\u7528\u914d\u7f6e(microservice.yaml\uff09 servicecomb: config: client: serverUri: https://servicecomb.cn-north-1.myhwclouds.com:443 \u8be5\u914d\u7f6e\u9879\u914d\u7f6e\u4e86\u914d\u7f6e\u4e2d\u5fc3\u7684\u5730\u5740\u3002\u5176\u4e2d\uff0caddress\u53ef\u4ee5\u5728\u516c\u6709\u4e91\u201c\u5de5\u5177\u548c\u6848\u4f8b\u201d\u76ee\u5f55\u4e0b\u67e5\u5230\u5bf9\u5e94\u7684\u914d\u7f6e\u4e2d\u5fc3\u5730\u5740\uff0c\u4fee\u6539\u534f\u8bae\uff08http/https\uff09\u3001\u4e3b\u673a\u540d\uff08\u53ef\u80fd\u4f7f\u7528\u57df\u540d\uff09\u548c\u7aef\u53e3\u53f7\u3002","title":"\u914d\u7f6e\u53c2\u8003"},{"location":"start/deployment-on-cloud/#_8","text":"","title":"\u4f7f\u7528\u670d\u52a1\u6cbb\u7406"},{"location":"start/deployment-on-cloud/#_9","text":"\u670d\u52a1\u6cbb\u7406\u4e3b\u8981\u6d89\u53ca\u201c\u9694\u79bb\u201d\u3001\u201c\u7194\u65ad\u201d\u3001\u201c\u5bb9\u9519\u201d\u3001\u201c\u9650\u6d41\u201d\u3001\u201c\u8d1f\u8f7d\u5747\u8861\u201d\u7b49\u3002","title":"\u529f\u80fd\u63cf\u8ff0"},{"location":"start/deployment-on-cloud/#_10","text":"\u914d\u7f6e\u9879(microservice.yaml\uff09 \u9700\u8981\u589e\u52a0\u4e0b\u9762\u6cbb\u7406\u76f8\u5173\u7684handler\uff0c\u624d\u80fd\u5728\u4ece\u914d\u7f6e\u4e2d\u5fc3\u5b9e\u65f6\u83b7\u53d6\u6cbb\u7406\u6570\u636e\u3002 servicecomb: handler: chain: Provider: default: bizkeeper-provider,qps-flowcontrol-provider Consumer: default: bizkeeper-consumer,loadbalance,qps-flowcontrol-consumer","title":"\u914d\u7f6e\u53c2\u8003"},{"location":"start/deployment-on-cloud/#_11","text":"","title":"\u4f7f\u7528\u6545\u969c\u6ce8\u5165"},{"location":"start/deployment-on-cloud/#_12","text":"\u6545\u969c\u6ce8\u5165\u4e3b\u8981\u63d0\u4f9b\u4e86\u5ef6\u65f6\u3001\u9519\u8bef\u4e24\u79cd\u7c7b\u578b\u6545\u969c\u3002","title":"\u529f\u80fd\u63cf\u8ff0"},{"location":"start/deployment-on-cloud/#_13","text":"\u914d\u7f6e\u9879(microservice.yaml\uff09 \u9700\u8981\u589e\u52a0\u4e0b\u9762\u6cbb\u7406\u76f8\u5173\u7684handler\u3002 servicecomb: handler: chain: Consumer: default: loadbalance,fault-injection-consumer","title":"\u914d\u7f6e\u53c2\u8003"},{"location":"start/deployment-on-cloud/#_14","text":"","title":"\u4f7f\u7528\u7070\u5ea6\u53d1\u5e03"},{"location":"start/deployment-on-cloud/#_15","text":"\u8be5\u529f\u80fd\u5bf9\u5e94\u4e8e\u5fae\u670d\u52a1\u76ee\u5f55\u7070\u5ea6\u53d1\u5e03\u529f\u80fd\u3002\u7ba1\u7406\u5458\u53ef\u4ee5\u901a\u8fc7\u4e0b\u53d1\u89c4\u5219\uff0c\u5bf9\u670d\u52a1\u8fdb\u884c\u7070\u5ea6\u53d1\u5e03\u7ba1\u7406\u3002","title":"\u529f\u80fd\u63cf\u8ff0"},{"location":"start/deployment-on-cloud/#_16","text":"\u589e\u52a0\u4f9d\u8d56\u5173\u7cfb(pom.xml) \u5f15\u5165\u5fc5\u8981\u7684jar\u5305\u3002 <dependency> <groupId>com.huawei.paas.cse</groupId> <artifactId>cse-handler-cloud-extension</artifactId> </dependency> \u5728Consumer\u7aef\u914d\u7f6e\u8d1f\u8f7d\u5747\u8861(microservice.yaml\uff09 \u5728\u8d1f\u8f7d\u5747\u8861\u6a21\u5757\u542f\u7528\u4e86\u7070\u5ea6\u53d1\u5e03\u7684filter\u3002 servicecomb: loadbalance: serverListFilters: darklaunch serverListFilter: darklaunch: className: com.huawei.paas.darklaunch.DarklaunchServerListFilter","title":"\u914d\u7f6e\u53c2\u8003"},{"location":"start/deployment-on-cloud/#_17","text":"","title":"\u4f7f\u7528\u8c03\u7528\u94fe"},{"location":"start/deployment-on-cloud/#_18","text":"\u534e\u4e3a\u4e91\u63d0\u4f9b\u4e86\u4e1a\u52a1\u65e0\u4fb5\u5165\u7684\u57cb\u70b9\u529f\u80fdAPM\u3002\u53ea\u9700\u8981\u901a\u8fc7\u534e\u4e3a\u4e91\u90e8\u7f72\u5bb9\u5668\u5e94\u7528\uff0c\u5e76\u9009\u62e9\u542f\u7528\u8c03\u7528\u94fe\u76d1\u63a7\u529f\u80fd\uff0c\u5373\u53ef\u4f7f\u7528\u8c03\u7528\u94fe\u670d\u52a1\u3002","title":"\u529f\u80fd\u63cf\u8ff0"},{"location":"start/deployment-on-cloud/#_19","text":"","title":"\u5fae\u670d\u52a1\u8fd0\u884c\u6570\u636e\u4e0a\u62a5"},{"location":"start/deployment-on-cloud/#_20","text":"\u5fae\u670d\u52a1\u53ef\u4ee5\u5c06\u81ea\u5df1\u7684\u8fd0\u884c\u6570\u636e\u4e0a\u62a5\u7ed9Dashboard\u670d\u52a1\uff0c\u5728\u516c\u6709\u4e91\u4e0a\u67e5\u770b\u4eea\u8868\u76d8\u6570\u636e\u3001\u5206\u5e03\u5f0f\u4e8b\u52a1\u6570\u636e\u7b49\u3002\u8be5\u7ae0\u8282\u662f\u63cf\u8ff0\u5982\u4f55\u542f\u7528\u5fae\u670d\u52a1\u6570\u636e\u4e0a\u62a5\u529f\u80fd\u3002","title":"\u529f\u80fd\u63cf\u8ff0"},{"location":"start/deployment-on-cloud/#_21","text":"\u589e\u52a0\u4f9d\u8d56\u5173\u7cfb(pom.xml) \u5f15\u5165\u5fc5\u8981\u7684jar\u5305\u3002 <dependency> \u3000\u3000<groupId>com.huawei.paas.cse</groupId> \u3000\u3000<artifactId>cse-handler-cloud-extension</artifactId> </dependency> \u914d\u7f6ehandler \u4eea\u8868\u76d8\u6570\u636e\u4f9d\u8d56\u4e8e\u4e24\u4e2ahandler\uff0c\u4e00\u4e2abizkeeper-provider\uff08\u5ba2\u6237\u7aef\u4e3abizkeeper-consumer\uff09\uff0c\u4e00\u4e2aperf-stats\uff0c\u6240\u4ee5\u5bf9\u5e94\u7684pom\u4f9d\u8d56\u9700\u8981\u5148\u5f15\u5165\u3002 servicecomb: handler: chain: Provider: default: bizkeeper-provider,perf-stats,tracing-provider,sla-provider Consumer: default: bizkeeper-consumer,loadbalance,perf-stats,tracing-consumer,sla-consumer \u914d\u7f6e\u4e0a\u62a5monitor\u5730\u5740 TenantLB_ADDRESS\u4e3a\u5171\u6709\u4e91\u79df\u6237\u7ba1\u7406\u9762\u63a5\u5165\u5730\u5740\uff0c\u9ed8\u8ba4\u662f100.125.1.34\u3002 servicecomb: service: registry: address: https://${TenantLB_ADDRESS}:30100 monitor: client: serverUri: https://${TenantLB_ADDRESS}:30109","title":"\u914d\u7f6e\u53c2\u8003"},{"location":"start/deployment-on-cloud/#tcc","text":"","title":"\u5206\u5e03\u5f0f\u4e8b\u52a1: TCC"},{"location":"start/deployment-on-cloud/#_22","text":"\u4e3b\u8981\u5b9e\u73b0\u57fa\u4e8eTCC\u534f\u8bae\u7684\u5206\u5e03\u5f0f\u670d\u52a1\u95f4\u7684\u6700\u7ec8\u4e00\u81f4\u6027\u65b9\u6848\uff0c\u4fdd\u969c\u4e00\u822c\u573a\u666f\u4e0b\u7684\u5e94\u7528\u4e00\u81f4\u6027\u9700\u6c42\uff0c\u5e76\u53ef\u4ee5\u5728FusionStage/ServiceStage\u5206\u5e03\u5f0f\u4e8b\u52a1\u754c\u9762\u67e5\u770b\u4e8b\u52a1\u8be6\u7ec6\u4fe1\u606f\u3002","title":"\u529f\u80fd\u63cf\u8ff0"},{"location":"start/deployment-on-cloud/#_23","text":"\u589e\u52a0\u4f9d\u8d56\u5173\u7cfb(pom.xml) \u5f15\u5165\u5fc5\u8981\u7684jar\u5305 <dependency> \u3000\u3000<groupId>com.huawei.paas.cse</groupId> \u3000\u3000<artifactId>cse-handler-tcc</artifactId> </dependency> \u914d\u7f6e\u9879\u53c2\u8003 \u9700\u8981\u589e\u52a0\u4e0b\u9762\u4e8b\u52a1\u76f8\u5173\u7684handler\uff0c\u624d\u80fd\u5728\u4ece\u914d\u7f6e\u4e2d\u5fc3\u5b9e\u65f6\u83b7\u53d6\u6cbb\u7406\u6570\u636e\u3002 servicecomb: handler: chain: Provider: default: tcc-client,bizkeeper-provider Consumer: default: tcc-server,bizkeeper-consumer,loadbalance","title":"\u914d\u7f6e\u53c2\u8003"},{"location":"start/development-environment/","text":"Prepare the local development environment JDK, Maven, Eclipse, and IDEA is required. If you already have these development tools installed, skip this section. JDK version and installation steps 1.JDK version The JDK version requires 1.8 or higher. 2.JDK download Please go to the official address of JDK version 1.8 to download. 3.JDK installation After downloading the JDK installation package on the official website, select the appropriate installation path to install the JDK. Here is the windows system as an example: Set the JAVA_HOME environment variable to point to the Java installation directory. Add %JAVA_HOME%\\bin to the system path path. After the environment variable is configured, use the java -version command to verify whether the installation is successful. The windows environment is echoed as follows: C:\\> java -version java version \"1.8.0_121\" Java(TM) SE Runtime Environment (build 1.8.0_121-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode) Maven installation steps Maven is a development tool that integrates project management, code compilation and more. Prerequisites The JDK has been installed successfully. installation steps Download the Maven installation package at the official address. Unzip the Maven installation package to the native path. Set environment variables\uff1a Set the M2_HOME environment variable to point to the Maven installation directory. Add %M2_HOME%\\bin to the system path path. Verification Use the mvn -version command to verify that the installation is successful. The windows environment is echoed as follows: C:\\>mvn -version Apache Maven 3.3.9 Eclipse installation Prerequisites a.JDK has been installed. b.Maven is already installed. installation steps a. Download the Eclipse installation package at the official address. b. Install Eclipse to the machine. c. (Optional) Extract the plugin m2eclipse described in the previous Maven installation to the plugins and features directory in the Eclipse installation directory. The latest Eclipse version With the Maven plugin, don't do this d. Start Eclipse, configure jre, maven settings, and the default encoding format is utf-8. IDEA installation Prerequisites a.JDK has been installed. b.Maven is already installed. installation steps a. Download the IDEA installation package on the official website, the paid version or the community version according to individual needs. b. Set the encoding format to utf-8. Open IDEA and select File -> Settings -> Editor -> File Encoding Change project Encoding and default encoding for properties files to utf-8. c. Set up maven configuration Open IDEA and select File -> Settings -> Build, Execution, Deployment -> Bulid Tools -> Maven Note configuring Maven home directory and User settings file","title":"Development environment"},{"location":"start/development-environment/#prepare-the-local-development-environment","text":"JDK, Maven, Eclipse, and IDEA is required. If you already have these development tools installed, skip this section.","title":"Prepare the local development environment"},{"location":"start/development-environment/#jdk-version-and-installation-steps","text":"1.JDK version The JDK version requires 1.8 or higher. 2.JDK download Please go to the official address of JDK version 1.8 to download. 3.JDK installation After downloading the JDK installation package on the official website, select the appropriate installation path to install the JDK. Here is the windows system as an example: Set the JAVA_HOME environment variable to point to the Java installation directory. Add %JAVA_HOME%\\bin to the system path path. After the environment variable is configured, use the java -version command to verify whether the installation is successful. The windows environment is echoed as follows: C:\\> java -version java version \"1.8.0_121\" Java(TM) SE Runtime Environment (build 1.8.0_121-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)","title":"JDK version and installation steps"},{"location":"start/development-environment/#maven-installation-steps","text":"Maven is a development tool that integrates project management, code compilation and more.","title":"Maven installation steps"},{"location":"start/development-environment/#prerequisites","text":"The JDK has been installed successfully.","title":"Prerequisites"},{"location":"start/development-environment/#installation-steps","text":"Download the Maven installation package at the official address. Unzip the Maven installation package to the native path. Set environment variables\uff1a Set the M2_HOME environment variable to point to the Maven installation directory. Add %M2_HOME%\\bin to the system path path. Verification Use the mvn -version command to verify that the installation is successful. The windows environment is echoed as follows: C:\\>mvn -version Apache Maven 3.3.9","title":"installation steps"},{"location":"start/development-environment/#eclipse-installation","text":"","title":"Eclipse installation"},{"location":"start/development-environment/#prerequisites_1","text":"a.JDK has been installed. b.Maven is already installed.","title":"Prerequisites"},{"location":"start/development-environment/#installation-steps_1","text":"a. Download the Eclipse installation package at the official address. b. Install Eclipse to the machine. c. (Optional) Extract the plugin m2eclipse described in the previous Maven installation to the plugins and features directory in the Eclipse installation directory. The latest Eclipse version With the Maven plugin, don't do this d. Start Eclipse, configure jre, maven settings, and the default encoding format is utf-8.","title":"installation steps"},{"location":"start/development-environment/#idea-installation","text":"","title":"IDEA installation"},{"location":"start/development-environment/#prerequisites_2","text":"a.JDK has been installed. b.Maven is already installed.","title":"Prerequisites"},{"location":"start/development-environment/#installation-steps_2","text":"a. Download the IDEA installation package on the official website, the paid version or the community version according to individual needs. b. Set the encoding format to utf-8. Open IDEA and select File -> Settings -> Editor -> File Encoding Change project Encoding and default encoding for properties files to utf-8. c. Set up maven configuration Open IDEA and select File -> Settings -> Build, Execution, Deployment -> Bulid Tools -> Maven Note configuring Maven home directory and User settings file","title":"installation steps"},{"location":"start/first-sample/","text":"Develop the first microservice Preparement Before developing the first Java-Chassis microservice, please make sure that your local development environment is prepared. See more details about this in Prepare the local development environment . The Apache Service Center is needed in this show case. About using service center, please refer to Install of ServiceCenter . Develop a HelloWorld microservice pom configurations First, please to create an empty maven project. It is suggested that the dependencies should be managed by dependencyManagement item, so that only the solution-basic is needed to be imported as dependency: <dependencyManagement> <dependencies> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>java-chassis-dependencies</artifactId> <version>${java-chassis-dependencies.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>solution-basic</artifactId> </dependency> </dependencies> solution-basic has contains almost all of the dependencies you need in the common cases. For the version 2.0.0 Java-Chassis, maven-compiler-plugin compilation plugin is also needed, which can make the method argument names preserved during the source project is build into a jar file. <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <compilerArgument>-parameters</compilerArgument> <encoding>UTF-8</encoding> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> add microservice configurations By default, Java-Chassis read configurations from the file named microservice.yaml placed in resources directory. The content of the file is like below. APPLICATION_ID: sample # this microservice belongs to the sample application service_description: name: helloworld # this microservice is named \"helloworld\" version: 1.0.0 servicecomb: service: registry: address: http://127.0.0.1:30100 # this address of the service center rest: address: 0.0.0.0:8080 Main class Add a main class in the project: package org.apache.servicecomb.samples; import org.apache.servicecomb.foundation.common.utils.BeanUtils; public class AppMain { public static void main(String[] args) { BeanUtils.init(); } } Invoking the org.apache.servicecomb.foundation.common.utils.BeanUtils#init() method will trigger the boot up procedure including configuration loading, Spring application context loading, microservice registration. Write a REST service interface Add a REST service interface class to declare the request you want to handle. package org.apache.servicecomb.samples.service; import org.apache.servicecomb.provider.rest.common.RestSchema; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @RestSchema(schemaId = \"hello\") @RequestMapping(\"/\") public class HelloWorldService { @GetMapping(\"/hello\") public String hello() { return \"Hello world!\"; } } Add log configuration The solution-basic module introduces the log4j2 module. To enable it, a configuration file is needed. This file should be placed in resources\\log4j2.xml and the content is like below: <?xml version=\"1.0\" encoding=\"UTF-8\"?> <Configuration status=\"WARN\"> <Appenders> <Console name=\"Console\" target=\"SYSTEM_OUT\"> <PatternLayout pattern=\"%d{HH:mm:ss.SSS} [%t] %-5level %logger{36}[%L] - %msg%n\"/> </Console> </Appenders> <Loggers> <Root level=\"info\"> <AppenderRef ref=\"Console\"/> </Root> </Loggers> </Configuration> Start the microservice After completing the work above, the microservice can be started by running the AppMain class. Please visit the web page of local service center http://127.0.0.1:30103/ . If the helloworld microservice instance is found like below, the microservice is started successfully. If you visit the address http://127.0.0.1:8080/hello , you can see the response \"Hello world!\" from helloworld service. Now, your first Java-Chassis microservice is completed!. Additional The introduction demo is developed in Spring MVC style. And there are currently 3 ways to choose: Spring MVC JaxRS RPC Developers can quickly build a project in following ways: Download the samples project. servicecomb-samples provides many samples in hand. Spring MVC Sample JaxRS Sample POJO Sample Generate projects using archetypes Maven provide archetypes to generate projects. Java-chassis implements many types of archetypes, see LINK for details. Generate projects using ServiceComb Spring Initializer ServiceComb Spring Initializer is an graphic user interface to generate projects. See LINK","title":"Develop the first microservice"},{"location":"start/first-sample/#develop-the-first-microservice","text":"","title":"Develop the first microservice"},{"location":"start/first-sample/#preparement","text":"Before developing the first Java-Chassis microservice, please make sure that your local development environment is prepared. See more details about this in Prepare the local development environment . The Apache Service Center is needed in this show case. About using service center, please refer to Install of ServiceCenter .","title":"Preparement"},{"location":"start/first-sample/#develop-a-helloworld-microservice","text":"","title":"Develop a HelloWorld microservice"},{"location":"start/first-sample/#pom-configurations","text":"First, please to create an empty maven project. It is suggested that the dependencies should be managed by dependencyManagement item, so that only the solution-basic is needed to be imported as dependency: <dependencyManagement> <dependencies> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>java-chassis-dependencies</artifactId> <version>${java-chassis-dependencies.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>solution-basic</artifactId> </dependency> </dependencies> solution-basic has contains almost all of the dependencies you need in the common cases. For the version 2.0.0 Java-Chassis, maven-compiler-plugin compilation plugin is also needed, which can make the method argument names preserved during the source project is build into a jar file. <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <compilerArgument>-parameters</compilerArgument> <encoding>UTF-8</encoding> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build>","title":"pom configurations"},{"location":"start/first-sample/#add-microservice-configurations","text":"By default, Java-Chassis read configurations from the file named microservice.yaml placed in resources directory. The content of the file is like below. APPLICATION_ID: sample # this microservice belongs to the sample application service_description: name: helloworld # this microservice is named \"helloworld\" version: 1.0.0 servicecomb: service: registry: address: http://127.0.0.1:30100 # this address of the service center rest: address: 0.0.0.0:8080","title":"add microservice configurations"},{"location":"start/first-sample/#main-class","text":"Add a main class in the project: package org.apache.servicecomb.samples; import org.apache.servicecomb.foundation.common.utils.BeanUtils; public class AppMain { public static void main(String[] args) { BeanUtils.init(); } } Invoking the org.apache.servicecomb.foundation.common.utils.BeanUtils#init() method will trigger the boot up procedure including configuration loading, Spring application context loading, microservice registration.","title":"Main class"},{"location":"start/first-sample/#write-a-rest-service-interface","text":"Add a REST service interface class to declare the request you want to handle. package org.apache.servicecomb.samples.service; import org.apache.servicecomb.provider.rest.common.RestSchema; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @RestSchema(schemaId = \"hello\") @RequestMapping(\"/\") public class HelloWorldService { @GetMapping(\"/hello\") public String hello() { return \"Hello world!\"; } }","title":"Write a REST service interface"},{"location":"start/first-sample/#add-log-configuration","text":"The solution-basic module introduces the log4j2 module. To enable it, a configuration file is needed. This file should be placed in resources\\log4j2.xml and the content is like below: <?xml version=\"1.0\" encoding=\"UTF-8\"?> <Configuration status=\"WARN\"> <Appenders> <Console name=\"Console\" target=\"SYSTEM_OUT\"> <PatternLayout pattern=\"%d{HH:mm:ss.SSS} [%t] %-5level %logger{36}[%L] - %msg%n\"/> </Console> </Appenders> <Loggers> <Root level=\"info\"> <AppenderRef ref=\"Console\"/> </Root> </Loggers> </Configuration>","title":"Add log configuration"},{"location":"start/first-sample/#start-the-microservice","text":"After completing the work above, the microservice can be started by running the AppMain class. Please visit the web page of local service center http://127.0.0.1:30103/ . If the helloworld microservice instance is found like below, the microservice is started successfully. If you visit the address http://127.0.0.1:8080/hello , you can see the response \"Hello world!\" from helloworld service. Now, your first Java-Chassis microservice is completed!.","title":"Start the microservice"},{"location":"start/first-sample/#additional","text":"The introduction demo is developed in Spring MVC style. And there are currently 3 ways to choose: Spring MVC JaxRS RPC Developers can quickly build a project in following ways: Download the samples project. servicecomb-samples provides many samples in hand. Spring MVC Sample JaxRS Sample POJO Sample Generate projects using archetypes Maven provide archetypes to generate projects. Java-chassis implements many types of archetypes, see LINK for details. Generate projects using ServiceComb Spring Initializer ServiceComb Spring Initializer is an graphic user interface to generate projects. See LINK","title":"Additional"},{"location":"start/terminology/","text":"Table 1-1 Glossary Abbreviations English Chinese Acronyms MicroServices MicroServices \u5fae\u670d\u52a1 Microservices is a lightweight SOA architecture that is commonly used to describe a loosely coupled distributed architecture that is widely used in cloud applications and Internet applications. Provider Provider \u670d\u52a1\u63d0\u4f9b\u8005 The service of the called party in the microservice invocation relationship. Consumer Consumer \u670d\u52a1\u6d88\u8d39\u8005 The service that invokes the initiator in the microservice invocation relationship. Application Application \u5e94\u7528 A logical entity that represents a software application that represents a computer software application that has business functions presented to the user. An application built with a microservice architecture typically consists of multiple microservices. Instance Instance \u5fae\u670d\u52a1\u5b9e\u4f8b A minimal service and deployment unit for a microservice, usually corresponding to an application process. IAM Identity and Access Management \u8eab\u4efd\u53ca\u6743\u9650\u7ba1\u7406 Responsible for maintaining the management level, user, role, authorization relationship, user organization and other information in the PaaS system. And carry out authorization and authorization checks. AK/SK AK/SK Key AK/SK\u5bc6\u94a5 Access key/Secret key is a set of key pairs used for API authentication and access control. Service Service \u670d\u52a1 A service is a description of a functional object that is accessed on demand. In the application model, the service is generally oriented to the application. The application usage service needs to subscribe to the service first, then bind the service and use it. In some business scenarios, it may also need to pay according to usage. Load Balance Load Balance \u8d1f\u8f7d\u5747\u8861 When an application accesses a microservice with multiple instances, it involves routing load balancing. Load balancing policies can be configured through configuration files to support multiple load balancing routing policies such as random, round-robin, session hold, and response time based weights. Rate limit Rate limit \u9650\u6d41 When a resource becomes a bottleneck, the service framework needs to limit the access request of the consumer and start the flow control protection mechanism. Flow control is available on both the consumer and provider sides. On the service consumer side, the frequency of requests sent to a micro service provider can be limited; on the service provider side, the frequency of requests sent by each microservice consumer can be limited, or the total consumption of the service provider can be determined according to the resource consumption of the service provider. Request frequency limits to prevent services from crashing due to resource exhaustion. Service Degrade Service Degrade \u964d\u7ea7 Service downgrade mainly includes two strategies: masked downgrade and fault tolerant downgrade: shielded downgrade refers to the decision of the operation and maintenance personnel/developers when the trigger condition of the outside world reaches a certain critical value. Or a service is forced to downgrade. Fault-tolerant degradation means that when non-core services are unavailable, business logic can be released for faulty services to ensure the operation of core services. Fault tolarance Fault tolarance \u5bb9\u9519 Fault Tolerance is a processing strategy in the scenario where an exception occurs when a consumer accesses a service. After an exception occurs, the service framework automatically selects a new service route to invoke. Circuit Breaker Circuit Breaker \u7194\u65ad There is usually a dependency between microservices. The service invocation link may contain multiple microservices. If one or more service access delays in the link are too high, the request for the portal service will continue. Stacking, continue to consume more threads, io resources, and eventually the system bottleneck due to resource accumulation, resulting in more services unavailable, resulting in avalanche effect. The fuse mechanism is designed for the above scenario. When a target service responds slowly or a large number of timeouts occur, the service call is blown. For subsequent call requests, the target service is no longer called, directly returned, and resources are quickly released. The target service situation is improved and the call is resumed. Isolation Isolation \u9694\u79bb Service isolation is an anomaly detection mechanism. Common detection methods are request timeout, excessive traffic, and so on. The general setting parameters include the timeout period, the maximum number of concurrent requests, etc. When the timeout period or the maximum number of concurrent requests is exceeded, an exception is recorded and used to calculate the error rate and the number of error requests in the fuse mechanism. Service Mesh Service Mesh \u7f51\u683c\u670d\u52a1 An infrastructure layer service. In the process of micro-service, developers need to solve the problems introduced by applications running in distributed networks, such as fault tolerance, current limiting, load balancing, registration discovery, monitoring, etc. Service Mesh acts as the L4/L7 protocol agent. The application solves the problems caused by micro-services. Legacy Legacy \u9057\u7559\u7cfb\u7edf A legacy system is a software system that is still running and in use, but has entered the aging phase of the software lifecycle.","title":"Glossary"},{"location":"start/terminology/#table-1-1-glossary","text":"Abbreviations English Chinese Acronyms MicroServices MicroServices \u5fae\u670d\u52a1 Microservices is a lightweight SOA architecture that is commonly used to describe a loosely coupled distributed architecture that is widely used in cloud applications and Internet applications. Provider Provider \u670d\u52a1\u63d0\u4f9b\u8005 The service of the called party in the microservice invocation relationship. Consumer Consumer \u670d\u52a1\u6d88\u8d39\u8005 The service that invokes the initiator in the microservice invocation relationship. Application Application \u5e94\u7528 A logical entity that represents a software application that represents a computer software application that has business functions presented to the user. An application built with a microservice architecture typically consists of multiple microservices. Instance Instance \u5fae\u670d\u52a1\u5b9e\u4f8b A minimal service and deployment unit for a microservice, usually corresponding to an application process. IAM Identity and Access Management \u8eab\u4efd\u53ca\u6743\u9650\u7ba1\u7406 Responsible for maintaining the management level, user, role, authorization relationship, user organization and other information in the PaaS system. And carry out authorization and authorization checks. AK/SK AK/SK Key AK/SK\u5bc6\u94a5 Access key/Secret key is a set of key pairs used for API authentication and access control. Service Service \u670d\u52a1 A service is a description of a functional object that is accessed on demand. In the application model, the service is generally oriented to the application. The application usage service needs to subscribe to the service first, then bind the service and use it. In some business scenarios, it may also need to pay according to usage. Load Balance Load Balance \u8d1f\u8f7d\u5747\u8861 When an application accesses a microservice with multiple instances, it involves routing load balancing. Load balancing policies can be configured through configuration files to support multiple load balancing routing policies such as random, round-robin, session hold, and response time based weights. Rate limit Rate limit \u9650\u6d41 When a resource becomes a bottleneck, the service framework needs to limit the access request of the consumer and start the flow control protection mechanism. Flow control is available on both the consumer and provider sides. On the service consumer side, the frequency of requests sent to a micro service provider can be limited; on the service provider side, the frequency of requests sent by each microservice consumer can be limited, or the total consumption of the service provider can be determined according to the resource consumption of the service provider. Request frequency limits to prevent services from crashing due to resource exhaustion. Service Degrade Service Degrade \u964d\u7ea7 Service downgrade mainly includes two strategies: masked downgrade and fault tolerant downgrade: shielded downgrade refers to the decision of the operation and maintenance personnel/developers when the trigger condition of the outside world reaches a certain critical value. Or a service is forced to downgrade. Fault-tolerant degradation means that when non-core services are unavailable, business logic can be released for faulty services to ensure the operation of core services. Fault tolarance Fault tolarance \u5bb9\u9519 Fault Tolerance is a processing strategy in the scenario where an exception occurs when a consumer accesses a service. After an exception occurs, the service framework automatically selects a new service route to invoke. Circuit Breaker Circuit Breaker \u7194\u65ad There is usually a dependency between microservices. The service invocation link may contain multiple microservices. If one or more service access delays in the link are too high, the request for the portal service will continue. Stacking, continue to consume more threads, io resources, and eventually the system bottleneck due to resource accumulation, resulting in more services unavailable, resulting in avalanche effect. The fuse mechanism is designed for the above scenario. When a target service responds slowly or a large number of timeouts occur, the service call is blown. For subsequent call requests, the target service is no longer called, directly returned, and resources are quickly released. The target service situation is improved and the call is resumed. Isolation Isolation \u9694\u79bb Service isolation is an anomaly detection mechanism. Common detection methods are request timeout, excessive traffic, and so on. The general setting parameters include the timeout period, the maximum number of concurrent requests, etc. When the timeout period or the maximum number of concurrent requests is exceeded, an exception is recorded and used to calculate the error rate and the number of error requests in the fuse mechanism. Service Mesh Service Mesh \u7f51\u683c\u670d\u52a1 An infrastructure layer service. In the process of micro-service, developers need to solve the problems introduced by applications running in distributed networks, such as fault tolerance, current limiting, load balancing, registration discovery, monitoring, etc. Service Mesh acts as the L4/L7 protocol agent. The application solves the problems caused by micro-services. Legacy Legacy \u9057\u7559\u7cfb\u7edf A legacy system is a software system that is still running and in use, but has entered the aging phase of the software lifecycle.","title":"Table 1-1 Glossary"},{"location":"transports/highway-rpc/","text":"Highway Concept Description Highway is ServiceComb's private high-performance protocol, it's suitable for the performance sensitive scenarios. Configuration To use the Highway channel, add the following dependencies in the pom.xml file: <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>transport-highway</artifactId> </dependency> The Highway configuration items in the microservice.yaml file are described below: Table 1-1 Highway configuration items Configuration Item Default Value Description servicecomb.highway.address The address that the server listens, empty for not listen, just a highway client servicecomb.highway.server.connection-limit Integer.MAX_VALUE Allow client maximum connections servicecomb.highway.server.thread-count verticle-count highway server verticle instance count(Deprecated) servicecomb.highway.server.verticle-count verticle-count highway server verticle instance count servicecomb.highway.client.thread-count verticle-count highway client verticle instance count(Deprecated) servicecomb.highway.client.verticle-count verticle-count highway client verticle instance count(Deprecated) ## Sample code An example of the Highway configuration in the microservice.yaml: servicecomb: highway: address: 0.0.0.0:7070","title":"Highway"},{"location":"transports/highway-rpc/#highway","text":"","title":"Highway"},{"location":"transports/highway-rpc/#concept-description","text":"Highway is ServiceComb's private high-performance protocol, it's suitable for the performance sensitive scenarios.","title":"Concept Description"},{"location":"transports/highway-rpc/#configuration","text":"To use the Highway channel, add the following dependencies in the pom.xml file: <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>transport-highway</artifactId> </dependency> The Highway configuration items in the microservice.yaml file are described below: Table 1-1 Highway configuration items Configuration Item Default Value Description servicecomb.highway.address The address that the server listens, empty for not listen, just a highway client servicecomb.highway.server.connection-limit Integer.MAX_VALUE Allow client maximum connections servicecomb.highway.server.thread-count verticle-count highway server verticle instance count(Deprecated) servicecomb.highway.server.verticle-count verticle-count highway server verticle instance count servicecomb.highway.client.thread-count verticle-count highway client verticle instance count(Deprecated) servicecomb.highway.client.verticle-count verticle-count highway client verticle instance count(Deprecated) ## Sample code An example of the Highway configuration in the microservice.yaml: servicecomb: highway: address: 0.0.0.0:7070","title":"Configuration"},{"location":"transports/http2/","text":"Http2 Scenario Users can easily enable Http2 protocol for better performance through configuration. External Service Communication Configuration The configuration for external service communication is in the microservice.yaml file. Enable h2(Http2 + TLS) Append sslEnabled=true to the listening address to enable TLS communication on server side. For details, see the section Using TLS Communication . Then add protocol=http2 to enable h2 communication. Here is the sample configuration: yaml servicecomb: rest: address: 0.0.0.0:8080?sslEnabled=true&protocol=http2 Enable h2c(Http2 without TLS) Simply add protocol=http2 to enable h2c communication in the server's configuration: yaml servicecomb: rest: address: 0.0.0.0:8080?protocol=http2 * The client will read the server's address configuration from service center, then communicate with the server by http2 protocol. Specific examples can refer to http2-it-tests http2 server configuration configuration default description notice servicecomb.rest.server.http2.useAlpnEnabled true Whether to enable ALPN servicecomb.rest.server.http2.HeaderTableSize 4096 servicecomb.rest.server.http2.pushEnabled true servicecomb.rest.server.http2.initialWindowSize 65535 servicecomb.rest.server.http2.maxFrameSize 16384 servicecomb.rest.server.http2.maxHeaderListSize Integer.MAX_VALUE servicecomb.rest.server.http2.concurrentStreams 100 The maximum stream concurrency supported in a connection The smaller value of the concurrentStreams on the server side and the multiplexingLimit on the client side http2 client configuration configuration default description notice servicecomb.rest.client.http2.useAlpnEnabled true Whether to enable ALPN servicecomb.rest.client.http2.multiplexingLimit -1 The maximum stream concurrency supported in a connection,-1 means no limit The smaller value of the concurrentStreams on the server side and the multiplexingLimit on the client side servicecomb.rest.client.http2.maxPoolSize 1 The maximum number of connections established for each IP:Port in each connection pool servicecomb.rest.client.http2.idleTimeoutInSeconds 0 The timeout period of the idle connection, the connection will be closed after the timeout","title":"HTTP2"},{"location":"transports/http2/#http2","text":"","title":"Http2"},{"location":"transports/http2/#scenario","text":"Users can easily enable Http2 protocol for better performance through configuration.","title":"Scenario"},{"location":"transports/http2/#external-service-communication-configuration","text":"The configuration for external service communication is in the microservice.yaml file. Enable h2(Http2 + TLS) Append sslEnabled=true to the listening address to enable TLS communication on server side. For details, see the section Using TLS Communication . Then add protocol=http2 to enable h2 communication. Here is the sample configuration: yaml servicecomb: rest: address: 0.0.0.0:8080?sslEnabled=true&protocol=http2 Enable h2c(Http2 without TLS) Simply add protocol=http2 to enable h2c communication in the server's configuration: yaml servicecomb: rest: address: 0.0.0.0:8080?protocol=http2 * The client will read the server's address configuration from service center, then communicate with the server by http2 protocol. Specific examples can refer to http2-it-tests","title":"External Service Communication Configuration"},{"location":"transports/http2/#http2-server-configuration","text":"configuration default description notice servicecomb.rest.server.http2.useAlpnEnabled true Whether to enable ALPN servicecomb.rest.server.http2.HeaderTableSize 4096 servicecomb.rest.server.http2.pushEnabled true servicecomb.rest.server.http2.initialWindowSize 65535 servicecomb.rest.server.http2.maxFrameSize 16384 servicecomb.rest.server.http2.maxHeaderListSize Integer.MAX_VALUE servicecomb.rest.server.http2.concurrentStreams 100 The maximum stream concurrency supported in a connection The smaller value of the concurrentStreams on the server side and the multiplexingLimit on the client side","title":"http2 server configuration"},{"location":"transports/http2/#http2-client-configuration","text":"configuration default description notice servicecomb.rest.client.http2.useAlpnEnabled true Whether to enable ALPN servicecomb.rest.client.http2.multiplexingLimit -1 The maximum stream concurrency supported in a connection,-1 means no limit The smaller value of the concurrentStreams on the server side and the multiplexingLimit on the client side servicecomb.rest.client.http2.maxPoolSize 1 The maximum number of connections established for each IP:Port in each connection pool servicecomb.rest.client.http2.idleTimeoutInSeconds 0 The timeout period of the idle connection, the connection will be closed after the timeout","title":"http2 client configuration"},{"location":"transports/rest-over-servlet/","text":"REST over Servlet The REST over Servlet mode applications runs in web container. You need to create a new servlet project to wrap the microservices, pack them into war packages, and load them into the web container to run. Path for external access Not like running as a standalone process, when the microservice runs in the web container, the web root and servlet url pattern will be different. For the traditional development framework, the consumer needs to perceive the complete url of the service; for example, the web root is /mywebapp, the url pattern is /rest, and the business-level path is /application, then consumer must access the service via the url /mywebapp/rest/application. So when the deployment pattern changes, like from web container to a standalone process, the consumer or producer have to modify the code to adapt to the changes. It is recommended to use ServiceComb's deployment decoupling feature. Whether it is a consumer or a producer, the application don't perceive the web root and url pattern in the code, while ServiceComb will automatically adapt them for the producer instance at runtime. For some legacy systems, if users expect to use restTemplate.getForObject(\"cse://serviceName/mywebapp/rest/application\"...) without too many changes, then the path of the interface should be defined as /mywebapp/rest/application: @RestSchema(schemaId = \"test\") @RequestMapping(path = \"/mywebapp/rest/application\") However, it is still recommended to use a deployment-independent way to write the code, which introduces less code modifications when the deployment pattern changes. maven dependencies <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>transport-rest-servlet</artifactId> </dependency> Configurations When integrating with servlet, there are a few concepts involved: Start spring context Note the following startup methods cannot be used at the same time, just choose one of them. Without SpringMVC UI or RestController xml <web-app xmlns=\"http://java.sun.com/xml/ns/javaee\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd\" version=\"3.0\"> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:META-INF/spring/*.bean.xml</param-value> </context-param> <listener> <listener-class>org.apache.servicecomb.transport.rest.servlet.RestServletContextListener</listener-class> </listener> </web-app> The classpath*:META-INF/spring/*.bean.xml configured in contextConfigLocation is optional, because the ServiceComb will ensure that it is included in the load path. This is just an example to indicate that the user can customize the contextConfigLocation. Use SpringMVC UI or RestController, and org.apache.servicecomb.transport.rest.servlet.CseDispatcherServlet exists xml <web-app xmlns=\"http://java.sun.com/xml/ns/javaee\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd\" version=\"3.0\"> <servlet> <servlet-name>SpringMVCServlet</servlet-name> <servlet-class>org.apache.servicecomb.transport.rest.servlet.CseDispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>SpringMVCServlet</servlet-name> <url-pattern>yourUrlPattern</url-pattern> </servlet-mapping> </web-app> Note This servlet is not the processing entry of ServiceComb, but the processing entry of UI or RestController. Use SpringMVC's UI or RestController, and there is no org.apache.servicecomb.transport.rest.servlet.CseDispatcherServlet In this case, the application class should inherit SpringMVC's DispatcherServlet, and then configure its implementation classes in CseDispatcherServlet's way. @Override protected WebApplicationContext createWebApplicationContext(ApplicationContext parent){ setContextClass(CseXmlWebApplicationContext.class); return super.createWebApplicationContext(parent); } ServiceComb servlet The url pattern can be set according to the business logic. The following /rest/* is just an example, not a fixed value. Url pattern must end with /* The following two declarations types can not be used at the same time. Standard declaration xml <web-app xmlns=\"http://java.sun.com/xml/ns/javaee\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd\" version=\"3.0\"> <servlet> <servlet-name>RestServlet</servlet-name> <servlet-class>org.apache.servicecomb.transport.rest.servlet.RestServlet</servlet-class> <load-on-startup>1</load-on-startup> <async-supported>true</async-supported> </servlet> <servlet-mapping> <servlet-name>RestServlet</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping> </web-app> Quick declaration yaml servicecomb.rest.servlet.urlPattern: /rest/* Specify urlPattern in the microservice.yaml file. When ServiceComb starts, it will automatically create RestServlet and set the corresponding urlPattern. Configuration example for typical scenarios Standard declaration in pure ServiceComb mode web.xml: xml <web-app xmlns=\"http://java.sun.com/xml/ns/javaee\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd\" version=\"3.0\"> <listener> <listener-class>org.apache.servicecomb.transport.rest.servlet.RestServletContextListener</listener-class> </listener> <servlet> <servlet-name>RestServlet</servlet-name> <servlet-class>org.apache.servicecomb.transport.rest.servlet.RestServlet</servlet-class> <load-on-startup>1</load-on-startup> <async-supported>true</async-supported> </servlet> <servlet-mapping> <servlet-name>RestServlet</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping> </web-app> Quick declaration in pure ServiceComb mode web.xml\uff1a xml <web-app xmlns=\"http://java.sun.com/xml/ns/javaee\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd\" version=\"3.0\"> <listener> <listener-class>org.apache.servicecomb.transport.rest.servlet.RestServletContextListener</listener-class> </listener> </web-app> microservice.yaml\uff1a yaml servicecomb.rest.servlet.urlPattern: /rest/* SpringMVC or RestController provide web services, ServiceComb proxy the requests as consumer web.xml\uff1a xml <web-app xmlns=\"http://java.sun.com/xml/ns/javaee\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd\" version=\"3.0\"> <servlet> <servlet-name>SpringMVCServlet</servlet-name> <servlet-class>org.apache.servicecomb.transport.rest.servlet.CseDispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>SpringMVCServlet</servlet-name> <url-pattern>yourUrlPattern</url-pattern> </servlet-mapping> </web-app> microservice.yaml\uff1a Servicecomb.rest.address and servicecomb.rest.servlet.urlPattern are not configured SpringMVC UI/RestController and ServiceComb provide services at the same time web.xml\uff1a xml <web-app xmlns=\"http://java.sun.com/xml/ns/javaee\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd\" version=\"3.0\"> <servlet> <servlet-name>SpringMVCServlet</servlet-name> <servlet-class>org.apache.servicecomb.transport.rest.servlet.CseDispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>SpringMVCServlet</servlet-name> <url-pattern>yourUrlPattern</url-pattern> </servlet-mapping> </web-app> microservice.yaml\uff1a yaml servicecomb: rest: servlet: urlPattern: /rest/* address: 0.0.0.0:8080 Things to notice with servlet filter RestServlet works in asynchronous mode. According to the servlet 3.0 standard, the entire work chain must be asynchronous. Therefore, the servlet filter should be set to be asynchronous when it's added to the chain: <filter> ...... <async-supported>true</async-supported> </filter> Configuration items The related items for REST over Servlet in the microservice.yaml are described below: Table1-1 REST over Servlet Configuration Items Configuration Item Default Value Required Description servicecomb.rest.address 0.0.0.0:8080 No The service listening address Should be the same with the web container's listening address servicecomb.rest.server.timeout -1 No Server aync servlet timeout in milliseconds, suggest set to -1 servicecomb.rest.server.requestWaitInPoolTimeout 30000 No for sync business logic, timeout in milliseconds for waiting in executor queue servicecomb.rest.servlet.urlPattern No Used to simplify servlet+servlet mapping config This item is used only when servlet+servlet mapping is not configured in web.xml.The format is:/* or /path/*, where path can be nested","title":"REST over Servlet"},{"location":"transports/rest-over-servlet/#rest-over-servlet","text":"The REST over Servlet mode applications runs in web container. You need to create a new servlet project to wrap the microservices, pack them into war packages, and load them into the web container to run.","title":"REST over Servlet"},{"location":"transports/rest-over-servlet/#path-for-external-access","text":"Not like running as a standalone process, when the microservice runs in the web container, the web root and servlet url pattern will be different. For the traditional development framework, the consumer needs to perceive the complete url of the service; for example, the web root is /mywebapp, the url pattern is /rest, and the business-level path is /application, then consumer must access the service via the url /mywebapp/rest/application. So when the deployment pattern changes, like from web container to a standalone process, the consumer or producer have to modify the code to adapt to the changes. It is recommended to use ServiceComb's deployment decoupling feature. Whether it is a consumer or a producer, the application don't perceive the web root and url pattern in the code, while ServiceComb will automatically adapt them for the producer instance at runtime. For some legacy systems, if users expect to use restTemplate.getForObject(\"cse://serviceName/mywebapp/rest/application\"...) without too many changes, then the path of the interface should be defined as /mywebapp/rest/application: @RestSchema(schemaId = \"test\") @RequestMapping(path = \"/mywebapp/rest/application\") However, it is still recommended to use a deployment-independent way to write the code, which introduces less code modifications when the deployment pattern changes.","title":"Path for external access"},{"location":"transports/rest-over-servlet/#maven-dependencies","text":"<dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>transport-rest-servlet</artifactId> </dependency>","title":"maven dependencies"},{"location":"transports/rest-over-servlet/#configurations","text":"When integrating with servlet, there are a few concepts involved: Start spring context Note the following startup methods cannot be used at the same time, just choose one of them. Without SpringMVC UI or RestController xml <web-app xmlns=\"http://java.sun.com/xml/ns/javaee\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd\" version=\"3.0\"> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:META-INF/spring/*.bean.xml</param-value> </context-param> <listener> <listener-class>org.apache.servicecomb.transport.rest.servlet.RestServletContextListener</listener-class> </listener> </web-app> The classpath*:META-INF/spring/*.bean.xml configured in contextConfigLocation is optional, because the ServiceComb will ensure that it is included in the load path. This is just an example to indicate that the user can customize the contextConfigLocation. Use SpringMVC UI or RestController, and org.apache.servicecomb.transport.rest.servlet.CseDispatcherServlet exists xml <web-app xmlns=\"http://java.sun.com/xml/ns/javaee\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd\" version=\"3.0\"> <servlet> <servlet-name>SpringMVCServlet</servlet-name> <servlet-class>org.apache.servicecomb.transport.rest.servlet.CseDispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>SpringMVCServlet</servlet-name> <url-pattern>yourUrlPattern</url-pattern> </servlet-mapping> </web-app> Note This servlet is not the processing entry of ServiceComb, but the processing entry of UI or RestController. Use SpringMVC's UI or RestController, and there is no org.apache.servicecomb.transport.rest.servlet.CseDispatcherServlet In this case, the application class should inherit SpringMVC's DispatcherServlet, and then configure its implementation classes in CseDispatcherServlet's way. @Override protected WebApplicationContext createWebApplicationContext(ApplicationContext parent){ setContextClass(CseXmlWebApplicationContext.class); return super.createWebApplicationContext(parent); } ServiceComb servlet The url pattern can be set according to the business logic. The following /rest/* is just an example, not a fixed value. Url pattern must end with /* The following two declarations types can not be used at the same time. Standard declaration xml <web-app xmlns=\"http://java.sun.com/xml/ns/javaee\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd\" version=\"3.0\"> <servlet> <servlet-name>RestServlet</servlet-name> <servlet-class>org.apache.servicecomb.transport.rest.servlet.RestServlet</servlet-class> <load-on-startup>1</load-on-startup> <async-supported>true</async-supported> </servlet> <servlet-mapping> <servlet-name>RestServlet</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping> </web-app> Quick declaration yaml servicecomb.rest.servlet.urlPattern: /rest/* Specify urlPattern in the microservice.yaml file. When ServiceComb starts, it will automatically create RestServlet and set the corresponding urlPattern.","title":"Configurations"},{"location":"transports/rest-over-servlet/#configuration-example-for-typical-scenarios","text":"Standard declaration in pure ServiceComb mode web.xml: xml <web-app xmlns=\"http://java.sun.com/xml/ns/javaee\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd\" version=\"3.0\"> <listener> <listener-class>org.apache.servicecomb.transport.rest.servlet.RestServletContextListener</listener-class> </listener> <servlet> <servlet-name>RestServlet</servlet-name> <servlet-class>org.apache.servicecomb.transport.rest.servlet.RestServlet</servlet-class> <load-on-startup>1</load-on-startup> <async-supported>true</async-supported> </servlet> <servlet-mapping> <servlet-name>RestServlet</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping> </web-app> Quick declaration in pure ServiceComb mode web.xml\uff1a xml <web-app xmlns=\"http://java.sun.com/xml/ns/javaee\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd\" version=\"3.0\"> <listener> <listener-class>org.apache.servicecomb.transport.rest.servlet.RestServletContextListener</listener-class> </listener> </web-app> microservice.yaml\uff1a yaml servicecomb.rest.servlet.urlPattern: /rest/* SpringMVC or RestController provide web services, ServiceComb proxy the requests as consumer web.xml\uff1a xml <web-app xmlns=\"http://java.sun.com/xml/ns/javaee\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd\" version=\"3.0\"> <servlet> <servlet-name>SpringMVCServlet</servlet-name> <servlet-class>org.apache.servicecomb.transport.rest.servlet.CseDispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>SpringMVCServlet</servlet-name> <url-pattern>yourUrlPattern</url-pattern> </servlet-mapping> </web-app> microservice.yaml\uff1a Servicecomb.rest.address and servicecomb.rest.servlet.urlPattern are not configured SpringMVC UI/RestController and ServiceComb provide services at the same time web.xml\uff1a xml <web-app xmlns=\"http://java.sun.com/xml/ns/javaee\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd\" version=\"3.0\"> <servlet> <servlet-name>SpringMVCServlet</servlet-name> <servlet-class>org.apache.servicecomb.transport.rest.servlet.CseDispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>SpringMVCServlet</servlet-name> <url-pattern>yourUrlPattern</url-pattern> </servlet-mapping> </web-app> microservice.yaml\uff1a yaml servicecomb: rest: servlet: urlPattern: /rest/* address: 0.0.0.0:8080","title":"Configuration example for typical scenarios"},{"location":"transports/rest-over-servlet/#things-to-notice-with-servlet-filter","text":"RestServlet works in asynchronous mode. According to the servlet 3.0 standard, the entire work chain must be asynchronous. Therefore, the servlet filter should be set to be asynchronous when it's added to the chain: <filter> ...... <async-supported>true</async-supported> </filter>","title":"Things to notice with servlet filter"},{"location":"transports/rest-over-servlet/#configuration-items","text":"The related items for REST over Servlet in the microservice.yaml are described below: Table1-1 REST over Servlet Configuration Items Configuration Item Default Value Required Description servicecomb.rest.address 0.0.0.0:8080 No The service listening address Should be the same with the web container's listening address servicecomb.rest.server.timeout -1 No Server aync servlet timeout in milliseconds, suggest set to -1 servicecomb.rest.server.requestWaitInPoolTimeout 30000 No for sync business logic, timeout in milliseconds for waiting in executor queue servicecomb.rest.servlet.urlPattern No Used to simplify servlet+servlet mapping config This item is used only when servlet+servlet mapping is not configured in web.xml.The format is:/* or /path/*, where path can be nested","title":"Configuration items"},{"location":"transports/rest-over-vertx/","text":"REST over Vertx Configuration The REST over Vertx communication channel runs in standalone mode, it can be started in the main function. In the main function, you need to initialize logs and load service configuration. The code is as follow: import org.apache.servicecomb.foundation.common.utils.BeanUtils; import org.apache.servicecomb.foundation.common.utils.Log4jUtils; public class MainServer { public static void main(String[] args) throws Exception { \u3000Log4jUtils.init();// Log initialization \u3000BeanUtils.init(); // Spring bean initialization } } To use the REST over Vertx communication channel, add the following dependencies in the maven pom.xml file: <dependency> \u3000\u3000<groupId>org.apache.servicecomb</groupId> \u3000\u3000<artifactId>transport-rest-vertx</artifactId> </dependency> The REST over Vertx related configuration items in the microservice.yaml file are described as follows: Table 1-1 Configuration items for REST over Vertx Configuration Item Default Value Description servicecomb.rest.address listening address, empty for not listen, just a rest client servicecomb.rest.server.connection-limit Integer.MAX_VALUE Max allowed client connections servicecomb.rest.server.thread-count verticle-count rest server verticle instance count(Deprecated) servicecomb.rest.server.verticle-count verticle-count rest server verticle instance count servicecomb.rest.server.connection.idleTimeoutInSeconds 60 Timeout for server's idle connection, The idle connections will be closed servicecomb.rest.server.compression false Wether the server support compression servicecomb.rest.server.maxInitialLineLength 4096 The max initial line length of the request the server can process, unit is Byte servicecomb.rest.server.maxHeaderSize 32768 The max header size of the request the server can process, unit is Byte servicecomb.rest.server.maxFormAttributeSize 2048 The max form attribute size of the request the server can process, unit is Byte servicecomb.rest.server.compressionLevel 6 The gzip/deflate compression level servicecomb.rest.server.maxChunkSize 8192 The max HTTP chunk size, unit is Byte servicecomb.rest.server.decoderInitialBufferSize 128 The max initial buffer size for HttpObjectDecoder, unit is Byte servicecomb.rest.server.http2ConnectionWindowSize -1 HTTP/2 connection window size, unlimited servicecomb.rest.server.decompressionSupported false whether decompression is supported servicecomb.rest.client.thread-count verticle-count rest client verticle instance count(Deprecated) servicecomb.rest.client.verticle-count verticle-count rest client verticle instance count servicecomb.rest.client.connection.maxPoolSize 5 The maximum number of connections in each connection pool for an IP:port combination servicecomb.rest.client.connection.idleTimeoutInSeconds 30 Timeout for client's idle connection, The idle connections will be closed servicecomb.rest.client.connection.keepAlive true Whether to use long connections servicecomb.rest.client.connection.compression false Wether the client support compression servicecomb.rest.client.maxHeaderSize 8192 The max header size of the response the client can process, unit is Byte Supplementary Explanation The connection amount under extreme condition Assumption: servicecomb.rest.client.thread-count = 8 servicecomb.rest.client.connection.maxPoolSize = 5 there are 10 instances of microservice A In terms of client side, under the extreme condition: * for a client instance invoking microservice A, there are up to 400 connections.( 8 * 5 * 10 = 400 ) * if this client instance is also invoking another microservice B, and there are 10 instances of microservice B, then there are another 400 connections, and 800 connections in total. In terms of server side, under the extreme condition: * a client instance establishes up to 40 connections to a server instance.( 8 * 5 = 40 ) * n client instances establish up to 40 * n connections to a server instance. To improve performance, larger connection pools are needed. While the larger connection pools means the more connections. When the microservice instance scale reaches hundreds, some instances may handle tens of thousands of connections. Therefore, the developers need to make reasonable planning according to the actual condition. The planning of HTTP1.1 may be relatively complex, and sometimes there is no proper solution, in which case the http2 is recommended. Sample Code An example of the configuration in the microservice.yaml file for REST over Vertx: servicecomb: rest: address: 0.0.0.0:8080 thread-count: 1 references: hello: transport: rest version-rule: 0.0.1","title":"REST over Vertx"},{"location":"transports/rest-over-vertx/#rest-over-vertx","text":"","title":"REST over Vertx"},{"location":"transports/rest-over-vertx/#configuration","text":"The REST over Vertx communication channel runs in standalone mode, it can be started in the main function. In the main function, you need to initialize logs and load service configuration. The code is as follow: import org.apache.servicecomb.foundation.common.utils.BeanUtils; import org.apache.servicecomb.foundation.common.utils.Log4jUtils; public class MainServer { public static void main(String[] args) throws Exception { \u3000Log4jUtils.init();// Log initialization \u3000BeanUtils.init(); // Spring bean initialization } } To use the REST over Vertx communication channel, add the following dependencies in the maven pom.xml file: <dependency> \u3000\u3000<groupId>org.apache.servicecomb</groupId> \u3000\u3000<artifactId>transport-rest-vertx</artifactId> </dependency> The REST over Vertx related configuration items in the microservice.yaml file are described as follows: Table 1-1 Configuration items for REST over Vertx Configuration Item Default Value Description servicecomb.rest.address listening address, empty for not listen, just a rest client servicecomb.rest.server.connection-limit Integer.MAX_VALUE Max allowed client connections servicecomb.rest.server.thread-count verticle-count rest server verticle instance count(Deprecated) servicecomb.rest.server.verticle-count verticle-count rest server verticle instance count servicecomb.rest.server.connection.idleTimeoutInSeconds 60 Timeout for server's idle connection, The idle connections will be closed servicecomb.rest.server.compression false Wether the server support compression servicecomb.rest.server.maxInitialLineLength 4096 The max initial line length of the request the server can process, unit is Byte servicecomb.rest.server.maxHeaderSize 32768 The max header size of the request the server can process, unit is Byte servicecomb.rest.server.maxFormAttributeSize 2048 The max form attribute size of the request the server can process, unit is Byte servicecomb.rest.server.compressionLevel 6 The gzip/deflate compression level servicecomb.rest.server.maxChunkSize 8192 The max HTTP chunk size, unit is Byte servicecomb.rest.server.decoderInitialBufferSize 128 The max initial buffer size for HttpObjectDecoder, unit is Byte servicecomb.rest.server.http2ConnectionWindowSize -1 HTTP/2 connection window size, unlimited servicecomb.rest.server.decompressionSupported false whether decompression is supported servicecomb.rest.client.thread-count verticle-count rest client verticle instance count(Deprecated) servicecomb.rest.client.verticle-count verticle-count rest client verticle instance count servicecomb.rest.client.connection.maxPoolSize 5 The maximum number of connections in each connection pool for an IP:port combination servicecomb.rest.client.connection.idleTimeoutInSeconds 30 Timeout for client's idle connection, The idle connections will be closed servicecomb.rest.client.connection.keepAlive true Whether to use long connections servicecomb.rest.client.connection.compression false Wether the client support compression servicecomb.rest.client.maxHeaderSize 8192 The max header size of the response the client can process, unit is Byte","title":"Configuration"},{"location":"transports/rest-over-vertx/#supplementary-explanation","text":"The connection amount under extreme condition Assumption: servicecomb.rest.client.thread-count = 8 servicecomb.rest.client.connection.maxPoolSize = 5 there are 10 instances of microservice A In terms of client side, under the extreme condition: * for a client instance invoking microservice A, there are up to 400 connections.( 8 * 5 * 10 = 400 ) * if this client instance is also invoking another microservice B, and there are 10 instances of microservice B, then there are another 400 connections, and 800 connections in total. In terms of server side, under the extreme condition: * a client instance establishes up to 40 connections to a server instance.( 8 * 5 = 40 ) * n client instances establish up to 40 * n connections to a server instance. To improve performance, larger connection pools are needed. While the larger connection pools means the more connections. When the microservice instance scale reaches hundreds, some instances may handle tens of thousands of connections. Therefore, the developers need to make reasonable planning according to the actual condition. The planning of HTTP1.1 may be relatively complex, and sometimes there is no proper solution, in which case the http2 is recommended.","title":"Supplementary Explanation"},{"location":"transports/rest-over-vertx/#sample-code","text":"An example of the configuration in the microservice.yaml file for REST over Vertx: servicecomb: rest: address: 0.0.0.0:8080 thread-count: 1 references: hello: transport: rest version-rule: 0.0.1","title":"Sample Code"},{"location":"transports/transport/","text":"Communication Concepts ServiceComb uses two network channels, REST and Highway, both support encrypted Transport Layer Security (TLS) transmission. The REST channel provides services in the standard RESTful form. The consumer can call RESTful APIs with http client.","title":"Communication"},{"location":"transports/transport/#communication","text":"","title":"Communication"},{"location":"transports/transport/#concepts","text":"ServiceComb uses two network channels, REST and Highway, both support encrypted Transport Layer Security (TLS) transmission. The REST channel provides services in the standard RESTful form. The consumer can call RESTful APIs with http client.","title":"Concepts"},{"location":"transports/verticle-count/","text":"verticle-count name and default value Version prior to 1.2.0 Named thread-count, and the default value is 1, which has the following problems: The name is ambiguous The underlying ServiceComb is based on vertx. The communication layer logic is hosted by verticle, running in the eventloop thread, and no separate threads are created. So thread-count actually represents the number of verticle instances created, not the number of threads. The default value is too small Because there is no best configuration in all scenarios, the old version chose the most conservative default value, which leads to the adjustment of these parameters in most scenarios. 1.2.0 and later versions Renamed to verticle-count At the same time, the old thread-count is allowed, but the warning log is printed, reminding to switch to the new configuration. Default rule\uff1a If the number of CPUs is less than 8, the number of CPUs is taken. 8 if the number of CPUs is greater than or equal to 8. The relationship between Eventloop and verticle instances: Assuming the CPU is 2, vertx creates 2 * CPU by default, ie 4 Eventloop threads. Assuming the configuration server verticle count and client verticle count are both 3, then: Because it is not allowed to perform any blocking action in the Eventloop, combined with the above figure, we can know that when the CPU is fully utilized, it is meaningless to add the verticle instance. Users are advised to combine their actual scenarios to test and summarize the appropriate configuration values.","title":"verticle-count"},{"location":"transports/verticle-count/#verticle-count","text":"","title":"verticle-count"},{"location":"transports/verticle-count/#name-and-default-value","text":"Version prior to 1.2.0 Named thread-count, and the default value is 1, which has the following problems: The name is ambiguous The underlying ServiceComb is based on vertx. The communication layer logic is hosted by verticle, running in the eventloop thread, and no separate threads are created. So thread-count actually represents the number of verticle instances created, not the number of threads. The default value is too small Because there is no best configuration in all scenarios, the old version chose the most conservative default value, which leads to the adjustment of these parameters in most scenarios. 1.2.0 and later versions Renamed to verticle-count At the same time, the old thread-count is allowed, but the warning log is printed, reminding to switch to the new configuration. Default rule\uff1a If the number of CPUs is less than 8, the number of CPUs is taken. 8 if the number of CPUs is greater than or equal to 8.","title":"name and default value"},{"location":"transports/verticle-count/#the-relationship-between-eventloop-and-verticle-instances","text":"Assuming the CPU is 2, vertx creates 2 * CPU by default, ie 4 Eventloop threads. Assuming the configuration server verticle count and client verticle count are both 3, then: Because it is not allowed to perform any blocking action in the Eventloop, combined with the above figure, we can know that when the CPU is fully utilized, it is meaningless to add the verticle instance. Users are advised to combine their actual scenarios to test and summarize the appropriate configuration values.","title":"The relationship between Eventloop and verticle instances:"},{"location":"using-java-chassis-in-spring-boot/components-for-spring-boot/","text":"spring boot starter for java-chassis java-chassis provide different starters for spring boot. java-chassis 2.0.0 and above with spring boot 2.0 and above example java-chassis-spring-boot-starter-standalone For standalone applications: POM dependency\uff1a <dependencies> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>java-chassis-spring-boot-starter-standalone</artifactId> </dependency> </dependencies> java-chassis-spring-boot-starter-servlet For web applications: POM dependency\uff1a <dependencies> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>java-chassis-spring-boot-starter-servlet</artifactId> </dependency> </dependencies> dependency management for applications\uff1a <dependencyManagement> <dependencies> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>java-chassis-dependencies</artifactId> <version>2.0.0-SNAPSHOT</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> java-chassis 1.3.0 and above with spring boot 2.0 and above example spring-boot2-starter-standalone For standalone applications: POM dependency\uff1a <dependencies> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>spring-boot2-starter-standalone</artifactId> </dependency> </dependencies> spring-boot2-starter-servlet For web applications: POM dependency\uff1a <dependencies> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>spring-boot2-starter-servlet</artifactId> </dependency> </dependencies> dependency management for applications\uff1a <dependencyManagement> <dependencies> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>java-chassis-dependencies-springboot2</artifactId> <version>1.3.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> java-chassis 1.3.0 and above with spring boot 1.0 and above example spring-boot-starter-provider For standalone applications: POM dependency\uff1a <dependencies> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>spring-boot-starter-provider</artifactId> </dependency> </dependencies> spring-boot-starter-transport For web applications: POM dependency\uff1a <dependencies> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>spring-boot-starter-transport</artifactId> </dependency> </dependencies> dependency management for applications\uff1a <dependencyManagement> <dependencies> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>java-chassis-dependencies-springboot1</artifactId> <version>1.3.0</version> <type>pom</type> <scope>import</scope> </dependency> <!-- spring boot 1.5.14.RELEASE use a low version of validation-api, must override it --> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>2.0.0.Final</version> </dependency> </dependencies> </dependencyManagement>","title":"spring boot starter for java-chassis"},{"location":"using-java-chassis-in-spring-boot/components-for-spring-boot/#spring-boot-starter-for-java-chassis","text":"java-chassis provide different starters for spring boot.","title":"spring boot starter for java-chassis"},{"location":"using-java-chassis-in-spring-boot/components-for-spring-boot/#java-chassis-200-and-above-with-spring-boot-20-and-above-example","text":"java-chassis-spring-boot-starter-standalone For standalone applications: POM dependency\uff1a <dependencies> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>java-chassis-spring-boot-starter-standalone</artifactId> </dependency> </dependencies> java-chassis-spring-boot-starter-servlet For web applications: POM dependency\uff1a <dependencies> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>java-chassis-spring-boot-starter-servlet</artifactId> </dependency> </dependencies> dependency management for applications\uff1a <dependencyManagement> <dependencies> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>java-chassis-dependencies</artifactId> <version>2.0.0-SNAPSHOT</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>","title":"java-chassis 2.0.0 and above with spring boot 2.0 and above example"},{"location":"using-java-chassis-in-spring-boot/components-for-spring-boot/#java-chassis-130-and-above-with-spring-boot-20-and-above-example","text":"spring-boot2-starter-standalone For standalone applications: POM dependency\uff1a <dependencies> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>spring-boot2-starter-standalone</artifactId> </dependency> </dependencies> spring-boot2-starter-servlet For web applications: POM dependency\uff1a <dependencies> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>spring-boot2-starter-servlet</artifactId> </dependency> </dependencies> dependency management for applications\uff1a <dependencyManagement> <dependencies> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>java-chassis-dependencies-springboot2</artifactId> <version>1.3.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>","title":"java-chassis 1.3.0 and above with spring boot 2.0 and above example"},{"location":"using-java-chassis-in-spring-boot/components-for-spring-boot/#java-chassis-130-and-above-with-spring-boot-10-and-above-example","text":"spring-boot-starter-provider For standalone applications: POM dependency\uff1a <dependencies> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>spring-boot-starter-provider</artifactId> </dependency> </dependencies> spring-boot-starter-transport For web applications: POM dependency\uff1a <dependencies> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>spring-boot-starter-transport</artifactId> </dependency> </dependencies> dependency management for applications\uff1a <dependencyManagement> <dependencies> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>java-chassis-dependencies-springboot1</artifactId> <version>1.3.0</version> <type>pom</type> <scope>import</scope> </dependency> <!-- spring boot 1.5.14.RELEASE use a low version of validation-api, must override it --> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>2.0.0.Final</version> </dependency> </dependencies> </dependencyManagement>","title":"java-chassis 1.3.0 and above with spring boot 1.0 and above example"},{"location":"using-java-chassis-in-spring-boot/diff-between-java-web/","text":"Both development methods will enable the full functionality of the java chassis. The JAVA application mode runs on a separate HTTP server (based on vert.x), which has great advantages in performance. The web development method runs on Tomcat or other built-in web servers and receives requests as a servlet. Therefore, during the development process, you can use some functions provided by the web container, such as providing page services and using Filter. When the application only needs to provide REST services, and performance requirements are high, it is recommended to use a JAVA application mode.","title":"The difference between JAVA application method and Web development method"},{"location":"using-java-chassis-in-spring-boot/diff-spring-mvc/","text":"Java chassis supports the use of the label (org.springframework.web.bind.annotation) provided by Spring MVC to declare the REST interface, but the two are independent implementations and have different design goals. The goal of the java chassis is to provide a cross-language framework that supports multiple communication protocols. Therefore, some features of Spring MVC that are not very good for cross-language support are removed, and features that are strongly related to a specific running framework are not supported, such as direct access to the Servlet protocol definition. HttpServletRequest. Here are some notable differences. Service declaration method Spring MVC uses @RestController to declare the service, and java chassis uses @RestSchema to declare the service and needs to display the service path using @RequestMapping to distinguish whether the service uses Spring MVC Annotations or JAX RS Annotations. @RestSchema(schemaId = \"hello\") @RequestMapping(path = \"/\") The schema is the service contract of java chassis, which is the basis of service runtime. Service management, codec and so on are all based on contract. In a cross-language scenario, the contract also defines the parts of the language that can be understood simultaneously. Data type support With Spring MVC, you can use multiple data types in a service definition as long as it can be serialized and deserialized by json. Such as: // abstract type Public void postData(@RequestBody Object data) // Interface definition Public void postData(@RequestBody IPerson interfaceData) // Generics tpye without specified type Public void postData(@RequestBody Map rawData) // specific protocol related types Public void postData(HttpServletRequest request) The above types are not supported in the java chassis. Because java chassis will generate contracts according to the interface definition, from the above interface definition, if you do not combine the actual implementation code or additional development documentation, you can not directly generate the contract. That is, standing in the REST perspective of the browser, I don't know how to construct the message content in the body. To support rapid development, the data type restrictions of java chassis are also constantly expanding, such as support for HttpServletRequest, but when they are used, they are different from the semantics of the WEB server, such as the inability to directly manipulate the stream. Therefore, it is recommended that the developer use the type of contract that can be described as much as possible in the usage scenario so that the code is more readable. For more information on java chassis support for data types, please refer to the \"Supported Data Types\" section. Common Annotation Support The following is the java chassis support for Spring MVC common annotation. Tag Name Support Description RequestMapping Yes GetMapping Yes PutMapping Yes PostMapping Yes DeleteMapping Yes PatchMapping Yes RequestParam Yes CookieValue Yes PathVariable Yes RequestHeader Yes RequestBody Yes Currently supports application/json,plain/text RequestPart Yes For file upload scenarios, the corresponding tags are Part, MultipartFile ResponseBody No The return value defaults to the body return ResponseStatus No The error code returned can be specified by ApiResponse RequestAttribute No Servlet Protocol Related Tags SessionAttribute No Servlet Protocol Related Tags MatrixVariable No ModelAttribute No ControllerAdvice No CrossOrigin No ExceptionHandler No InitBinder No Other Using POJO objects for parameter mapping in GET methods is not supported. For example: public void getOperation(Person p) Do not support the use of Map mapping in the GET method for all possible parameters. For example: public void getOperation(Map<String,String> p)","title":"The difference in Spring MVC mode"},{"location":"using-java-chassis-in-spring-boot/java-application/","text":"Using JAVA integration, an efficient HTTP server and REST development framework has been added for Spring Boot applications. This way of integration is very simple. Just introduce the relevant dependencies into the project and use the @EnableServiceComb annotation. This project [code example] (https://github.com/huaweicse/servicecomb-java-chassis-samples/tree/master/spring-boot-simple) Introducing dependencies Add the spring-boot-starter-provider to the dependency to introduce the core functions of the java chassis. The purpose of introducing hibernate-validator is that spring boot will detect the implementation class of validation-api, and it will not start if it is not detected. <dependencyManagement> <dependencies> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>java-chassis-dependencies</artifactId> <version>1.0.0-m1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>spring-boot-starter-provider</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> </dependency> </dependencies> Enable the core functions of java chassis Add @EnableServiceComb in front of the startup class. @SpringBootApplication @EnableServiceComb public class WebsiteMain { public static void main(final String[] args) { SpringApplication.run(WebsiteMain.class, args); } } With the above configuration, you can fully use all the functions provided by the java chassis, use the java chassis to develop REST services, and open various governance functions. Configure microservices The microservice.yaml file allows you to customize the microservice information, including the application id, microservice name, listener address and port. After integrating java chassis, you can develop REST interface through it: @RestSchema(schemaId = \"hello\") @RequestMapping(path = \"/\") public class HelloService { @RequestMapping(path = \"hello\", method = RequestMethod.GET) public String sayHello(@RequestParam(name=\"name\") String name) { return \"Hello \" + name; } } Then you can access it by http://localhost:9093/hello?name=world.","title":"JAVA application development"},{"location":"using-java-chassis-in-spring-boot/spring-mvcmo-shi-de-cha-yi/","text":"","title":"Spring mvcmo shi de cha yi"},{"location":"using-java-chassis-in-spring-boot/using-java-chassis-in-spring-boot/","text":"Spring Boot \u53ef\u4ee5\u8ba9\u5f00\u53d1\u8005\u80fd\u591f\u66f4\u52a0\u5feb\u901f\u7684\u6784\u5efaSpring\u5e94\u7528\u3002\u4e3b\u8981\u63d0\u4f9b\u4e86\u5982\u4e0b\u529f\u80fd\uff1a \u521b\u5efa\u72ec\u7acb\u53ef\u6267\u884c\u7684Spring\u5e94\u7528\u3002\u901a\u8fc7\u5c06\u5e94\u7528\u7a0b\u5e8f\u6253\u5305\u4e3ajar\uff0c\u5c31\u53ef\u4ee5\u901a\u8fc7java -jar\u6765\u6267\u884c\u5e94\u7528\u7a0b\u5e8f\u3002 \u5185\u5d4cTomcat, Jetty\u7b49WEB\u670d\u52a1\u5668\uff0c\u800c\u4e0d\u9700\u8981\u5f00\u53d1\u8005\u6253\u5305war\u3002 \u63d0\u4f9bstarter\u7b80\u5316maven\u4f9d\u8d56\u5173\u7cfb\u914d\u7f6e\u3002 \u5c06Spring Boot\u7528\u4e8e\u5fae\u670d\u52a1\u5f00\u53d1\uff0c\u53ef\u4ee5\u6781\u5927\u7684\u7b80\u5316\u5f00\u53d1\u8005\u914d\u7f6e\u548c\u90e8\u7f72\u3002java-chassis\u63d0\u4f9b\u4e86\u5b8c\u5584\u7684\u7684\u670d\u52a1\u6cbb\u7406\u80fd\u529b\u3001\u826f\u597d\u7684\u8de8\u8bed\u8a00\u7279\u6027\u548c\u9ad8\u6548\u7684\u5f02\u6b65\u901a\u4fe1\u80fd\u529b\uff0c\u901a\u8fc7\u4f7f\u7528java chassis\uff0c\u53ef\u4ee5\u5feb\u901f\u542f\u7528\u5404\u79cd\u6ee1\u8db3\u5546\u4e1a\u8fd0\u7ef4\u9700\u8981\u7684\u529f\u80fd\u3002 \u672c\u6587\u5c06\u4ecb\u7ecd\u5982\u4f55\u5728Spring Boot\u4e2d\u96c6\u6210\u548c\u4f7f\u7528\u3002\u5f00\u53d1\u8005\u901a\u5e38\u4f1a\u4ee5\u5982\u4e0b\u51e0\u79cd\u65b9\u5f0f\u4f7f\u7528Spring Boot\uff1a JAVA\u5e94\u7528\u65b9\u5f0f\uff1a\u5f15\u5165spring-boot-starter\uff0c\u5f00\u53d1\u666e\u901aJAVA\u5e94\u7528\u3002\u8be5\u5e94\u7528\u4e0d\u4f1a\u542f\u52a8WEB\u670d\u52a1\u5668\u3002 Web\u5f00\u53d1\u65b9\u5f0f\uff1a\u5f15\u5165spring-boot-starter-web\uff0c\u5f00\u53d1Web\u5e94\u7528\u3002\u8be5\u5e94\u7528\u4f1a\u5305\u542b\u4e00\u4e2a\u5185\u5d4c\u7684Tomcat\u6216\u8005Jetty\u670d\u52a1\u5668\uff0c\u5e76\u4e14\u4f7f\u7528The Spring Web MVC framework\uff08\u7b80\u79f0Spring MVC\uff09\u5f00\u53d1REST\u63a5\u53e3\u3002 \u5728\u4e24\u79cd\u60c5\u51b5\u4e0b\uff0c\u90fd\u53ef\u4ee5\u96c6\u6210java chassis\uff0c\u539f\u7406\u56fe\u5982\u4e0b\uff1a JAVA\u5e94\u7528\u65b9\u5f0f \u8fd9\u79cd\u96c6\u6210\u65b9\u5f0f\u76f8\u5bf9\u7b80\u5355\uff0c\u76f8\u5f53\u4e8e\u76f4\u63a5\u5c06java chassis\u901a\u8fc7Spring Boot\u5e94\u7528\u62c9\u8d77\uff0c\u4e0d\u6d89\u53ca\u4efb\u4f55\u6539\u9020\u548c\u53d8\u5316\u3002 Web\u5f00\u53d1\u65b9\u5f0f \u8be5\u96c6\u6210\u65b9\u5f0f\u7684\u672c\u8d28\u662f\u5c06Spring MVC\u7684DispatcherServlet\u66ff\u6362\u4e3ajava chassis\u7684RestServlet\u3002","title":"Intruductions"},{"location":"using-java-chassis-in-spring-boot/web-application/","text":"The development steps of the web development mode and the JAVA application mode are similar. This project [code example] (https://github.com/huaweicse/servicecomb-java-chassis-samples/tree/master/spring-boot-web) Mainly differences: JAVA application is based on spring-boot-starter, and web development is based on spring-boot-starter-web. JAVA application depends on spring-boot-starter-provider, while web development depends on spring-boot-starter-transport. Spring-boot-starter-web already carries hibernate-validator and does not require additional dependencies. In the startup function, the web development mode can be declared @SpringBootApplication(exclude=DispatcherServletAutoConfiguration.class) To close org.springframework.web.servlet.DispatcherServlet, enable org.apache.servicecomb.transport.rest.servlet.RestServlet via @EnableServiceComb. Although it is not necessary to exclude the DispatcherServlet, it is not a good idea to have multiple REST frameworks in a microservice in most scenarios, which will cause much confusion in use. Specify the URL root path of the RestServlet in the microservice.yaml file via the configuration item servicecomb.rest.servlet.urlPattern. And the listening port in the configuration item servicecomb.rest.address must be consistent with the port that the tomcat listens on (the default is 8080, which can be modified by adding server.port in application.yml) After integrating java chassis, you can develop REST interface through it: @RestSchema(schemaId = \"hello\") @RequestMapping(path = \"/\") public class HelloService { @RequestMapping(path = \"hello\", method = RequestMethod.GET) public String sayHello(@RequestParam(name=\"name\") String name) { return \"Hello \" + name; } } Then you can access it by http://localhost:9093/hello?name=world. You can see that the tags used are mostly the same as Spring MVC. But there are also a few different places, such as: Replace RestController with RestSchema Declare @RequestMapping explicitly. If the business code is not a new development but based on the development of Spring MVC, now the java chassis is based on the transformation, but also need to pay attention to the disabling of the DispatcherServlet, and its related features will no longer take effect. In the following sections, about web JAVA application mode and web development mode, we'll introduce some details of the differences in Spring MVC mode.","title":"Web development method development"}]}