ServiceComb+Etcd
一、ServiceComb 概述
1.背景介绍
ServiceComb 作为Apache 开源组织下的一款微服务框架,其前身为华为云的 微服务引擎 CSE (Cloud Service Engine) 云服务。它意味着国内一款微服务框架在华为和Apache 组织的共同努力下, 随着微服务市场的火爆,一定会让越来越多的开发者所喜欢。
2.首要原则
3.技术方案
解决方案级,多语言、多通信协议、标准服务契约、事务最终一致性开源开放,拥抱SpringBoot、SpringCloud、ServiceMesh 等主流生态低门槛准入,业务侵入度低,架构松耦合
4.官方网站介绍
华为将 ServiceComb 贡献给了 Apache 基金组织后,我们就可以通过 Apache 的官方网站提供的资料来学习ServiceComb,下面是官网地址: 英文:http://servicecomb.incubator.apache.org/ 中文:http://servicecomb.incubator.apache.org/cn/
二、ServiceComb 与 SpringCloud 的比较
我们可以从语言框架,编程模型,通信协议,服务治理,服务访问,分布式事务等方面进行比较, 得出结果如下:
通过上图的对比,我们可以得出结论就是 ServiceComb 在微服务开发上更胜一筹。我们有理由 相信 ServiceComb 将会在微服务开发领域成为国人的骄傲。
三、ServiceComb 的开放性设计思想
1.编程模型和通信模型分离,不同的编程模型可以灵活组合不同的通信模型。应用开发者在开发阶 段只关注接口开发,部署阶段灵活切换通信方式;支持 legacy 系统的切换,legacy 系统只需要修改服务发布的配置文件(或者annotation),而不需要修改代码。 现阶段支持SpringMVC、JAX-RS 和透明RPC 三种开发方式。 2.内建 API-first 支持。通过契约规范化微服务开发,实现跨语言的通信,并支持配套的软件工具链 (契约生成代码、代码生成契约等)开发,构建完整的开发生态。 3.定义了常用的微服务运行模型,将微服务从发现到交互过程中的各种容错手段都封装起来。该运 行模型支持自定义和扩展。
四、ServiceComb 微服务解决方案
五、安装 ServiceComb 开发环境
应用开发环境所需安装的工具包括JDK、Maven、Eclipse 和 IDEA 。
六、服务注册中心 CSE 介绍
1.服务注册中心基本介绍
现在我们介绍如何在开发者本地进行消费者/提供者应用的开发调试。开发服务提供者和消费提供者 均需要连接到在远程的服务中心,为了本地微服务的开发和调试: 启动本地服务中心; 服务中心是微服务框架中的重要组件,用于服务元数据以及服务实例元数据的管理和处理注册、发 现。服务中心与微服务提供/消费者的逻辑关系下图所示:
2.启动本地服务中心
下 载 [ 服 务 注 册 中 心 可 执 行 文 件 压 缩 包 ] (http://apache.org/dyn/closer.cgi/incubator/servicecomb/incubator-servicecomb-service-center/1.0.0-m1/ap ache-servicecomb-incubating-service-center-1.0.0-m1-windows-amd64.tar.gz) 2. 解压缩到当前文件夹 3. 进入解压缩后的目录,然后双击运行start-service-center.bat文件 注意:Window 和Linux 版本均只支持 64 位系统。 {: .notice–warning} 以Docker 的方式运行 docker pull servicecomb/service-center docker run -d -p 30100:30100 servicecomb/service-center:latest 下载后的 CSE 服务注册中心,并打开目录结构如下:
打开 conf/app.conf 文件后,可以找到 CSE 基本配置如下: 服务端配置:
sever options
if you want to listen at ipv6 address, then set the httpaddr value like: # httpaddr = 2400:A480:AAAA:200::159 (global scope)
httpaddr = fe80::f816:3eff:fe17:c38b%eth0 (link-local scope) httpaddr = 127.0.0.1
httpport = 30100
read_header_timeout = 60s read_timeout = 60s idle_timeout = 60s write_timeout = 60s max_header_bytes = 32768 # 32K max_body_bytes = 2097152 # 2M
enable_pprof = 0
前端配置:
Frontend Configurations
frontend_host_ip = 127.0.0.1 frontend_host_port = 30103
2 .启动本地服务中心后,在服务提供/消费者的 microservice.yaml 文件中配置 ServerCenter 的地址和端口,示例代码:
servicecomb: service: registry: address: http://127.0.0.1:30100 #服务中心地址及端口
3.开发服务提供/消费者,启动微服务进行本地测试。 通过设置环境信息方便本地调试 通过 microservice.yaml 配置文件来指定
service_description: environment: development
七、使用官方提供的脚手架快速开发 ServiceComb
为了能够使开发者可以快速构建 ServiceComb 应用程序,它同样也为我们提供了一套脚手架,这样 能够方便学习者及应用开发者快速入门,同时极大的提高了效率。 1.访问快速开发引导页: http://start.servicecomb.io/ 页面如下:
后面我们就可以填写工程相关内容,最后就可以生成代码了。 下载后的工程
解压工程,导入到 Idea 工具中。
八、ServiceComb 服务的线程模型与通信协议
ServiceComb 实现了两种网络通道,包括 REST 和 Highway,均支持 TLS 加密传输。其中,REST 网 络通道将服务以标准 RESTful 形式发布,调用端兼容直接使用 http client 使用标准 RESTful 形式进行 调用。 1.线程模型 我们一起来了解 serviceComb 微服务的完整线程模型, IO 线程和业务线程之间的关系。 servicecComb 微服务的完整线程模型如下图所示:
2.通信协议 通过上面的线程模型的分析,我们发现最终业务线程和服务端线程通信的关键就在于他们的网络连 接和网络通信的过程,所以我们现在一起来学习一下 ServiceComb 中常用的通信协议有哪些?
我们通过下面的图可以看出有三种协议方式: 第一种 :HighWay 方式,这种方式其实就是我们常说的 RPC 方式。 第二种:Vertx REST 方式,这种方式也可以实现 WEB 开发,但我们一起用的少。 第三种:Servlet REST 方式,这种方式是我们现在用的最多的一种方式。
九、开发 RESTFUL 方式微服务入门程序
首先我们以 rest 方式来开发 servicecomb 的入门程序,通过该程序我们能够掌握 servicecomb 微 服务框架的 restful 方式开发基本步骤。 该程序的基本技术架构:springboot+servicecomb 1.服务程序基本结构 我们所构建的 servicecomb 入门程序的基本结构,如下图所示:
工程之间的结构关系,如下图所示:
2.父工程 servicecombrest 坐标引入 在父工程中 servicecombrest 的pom.xml 文件中添加相关的坐标。
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>cn.itcast.servicecomb</groupId> <artifactId>servicecomb-rest</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <modules> <module>serviceprovider</module> <module>serviceconsumer</module> <module>service-inerface</module> </modules> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <fastjson.version>1.2.47</fastjson.version> </properties> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.12.RELEASE</version> <relativePath/> <!-- lookup parent from repository <version>1.5.12.RELEASE</version>--> </parent> <dependencyManagement> <dependencies> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>java-chassis-dependencies</artifactId> <version>1.0.0-m2</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
3.子模块-服务接口 serviceinterface 打开 serviceinterface 子模块,并进入 src/main/java 目录下,创建 RestService 类 具体代码如下所示:
package cn.itcast.service; public interface RestService { public String restHello(String name); }
4.子模块-服务提供者 serviceprovider 打开模块后,模块结构图如下所示:
进入子模块 serviceprovider,打开 pom.xml 文件,添加如下坐标:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>servicecomb-rest</artifactId> <groupId>cn.itcast.servicecomb</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>service-provider</artifactId> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>spring-boot-starter-provider</artifactId> </dependency> <dependency> <groupId>cn.itcast.servicecomb</groupId> <artifactId>service-inerface</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>handler-flowcontrol-qps</artifactId> </dependency> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>handler-bizkeeper</artifactId> </dependency> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>handler-tracing-zipkin</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> </project>
编写 microservice.yaml 文件,具体配置如下:
APPLICATION_ID: start.servicecomb.io service_description: name: provider version: 0.0.1 servicecomb: circuitBreaker: Provider: provider: requestVolumeThreshold: 8 fallbackpolicy: provider: policy: returnnull flowcontrol: Provider: qps: limit: gateway: 100 handler: chain: Provider: default: qps-flowcontrol-provider,bizkeeper-provider,tracing-provider rest: address: 0.0.0.0:9080 service: registry: address: http://192.168.229.133:30100 autodiscovery: false
编写服务端 RestService 接口的实现类 RestProviderServiceImpl,如下所示:
package cn.itcast.service.impl; import cn.itcast.service.RestService; import org.apache.servicecomb.provider.rest.common.RestSchema; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; /**
-
以 rest 形式发布服务 */ @RestSchema(schemaId = "hello") @RequestMapping(path = "/hello") public class RestProviderServiceImpl implements RestService { @Override @GetMapping(path = "/hello") public String restHello(String name){ System.out.println(name); return "Hello World!"; } }
编写 springboot 的服务启动类,代码如下:
package cn.itcast; import org.apache.servicecomb.springboot.starter.provider.EnableServiceComb; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; /*
-
microservice.yaml 名称不得修改 */ @SpringBootApplication @EnableServiceComb public class RestProviderSpringBootApplication { public static void main(String[] args) { SpringApplication.run(RestProviderSpringBootApplication.class, args); } }
完成后,就可以启动 ServiceComb 的服务提供者程序。
5.子模块-服务消费者 serviceconsumer 进入服务消费方,打开子模块 serviceconsumer 工程,打开它下面的 pom.xml 文件,并加入如下坐标:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>servicecomb-rest</artifactId> <groupId>cn.itcast.servicecomb</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>service-consumer</artifactId> <dependencies> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>spring-boot-starter-provider</artifactId> </dependency> <dependency> <groupId>cn.itcast.servicecomb</groupId> <artifactId>service-inerface</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>handler-flowcontrol-qps</artifactId> </dependency> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>handler-bizkeeper</artifactId> </dependency> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>handler-tracing-zipkin</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> </project>
5.1 服务消费者 serviceconsumer 模块 目录结构如下:
5.2 编写 RestService 接口的实现类
package cn.itcast.service.impl; import cn.itcast.service.RestService; import org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; @Service public class RestConsumerServiceImpl implements RestService { private final RestTemplate restTemplate = RestTemplateBuilder.create(); public String restHello(String name) { //service url is : cse://serviceName/operation //provider 是 serviceprovider 项目中的 microservice.yaml 里面的 name 微服务名称 String serviceName = "provider"; String value = restTemplate.getForObject("cse://" + serviceName + "/hello/hello", String.class); System.out.println(value); return value; } }
5.3 编写 Controller 类
package cn.itcast.controller; import cn.itcast.service.RestService; import org.apache.servicecomb.provider.rest.common.RestSchema; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestSchema(schemaId="test") @RequestMapping("/test") public class RestConsumerController { @Autowired private RestService restService; @GetMapping(path="/test") public String restHello(){ return restService.restHello("aa"); } }
5.4 编写 Springboot 启动类
package cn.itcast; import org.apache.servicecomb.springboot.starter.provider.EnableServiceComb; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @EnableServiceComb @SpringBootApplication public class RestConsumerSrpingBootApplication { public static void main(String[] args) { SpringApplication.run(RestConsumerSrpingBootApplication.class, args); } }
6.服务运行测试
打开 CSE 服务注册中心 启动微服务的服务提供者 启动服务消费者
十、开发 RPC 方式微服务入门程序
通过以 REST 方式入门程序的介绍,我们基本理解了 ServiceComb 中服务的发布和消费。那么现在 我们以 RPC 方式同样介绍一下 ServiceComb 的服务发布与消费。它们不一样的就是服务的开发方式, 但最终效果都是一样的 1.服务程序基本结构 我们所构建的 servicecomb 入门程序的基本结构,如下图所示:
2.父工程 service-rpc 坐标引入 在父工程中 service-rpc 的 pom.xml 文件中添加相关的坐标
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>cn.itcast</groupId> <artifactId>servic-rpc</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <modules> <module>service-rpc-provider</module> <module>service-rpc-interface</module> <module>service-rpc-consumer</module> </modules> <name>servic-rpc</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.12.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> </project>
3.子模块-服务接口 service-rpc-interface 打开 service-rpc-interface 子模块,并进入 src/main/java 目录下,创建 RpcService 类 具体代码如下所示:
package cn.itcast.service; public interface RpcService { public String sayHello(String name); }
4.子模块-服务提供者 service-rpc-provider 打开模块后,模块结构图如下所示:
进入子模块 service-rpc-provider,打开 pom.xml 文件,添加如下坐标
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>servic-rpc</artifactId> <groupId>cn.itcast</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>service-rpc-provider</artifactId> <name>service-rpc-provider</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.3.5.Final</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>spring-boot-starter-provider</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!--transport 根据 microservice.yaml 中 endpoint 发布需求选择,本例中两者都引入,也可以二选 一--> <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> <dependency> <groupId>cn.itcast</groupId> <artifactId>service-rpc-interface</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>java-chassis-dependencies</artifactId>