2ServiceComb回顾
为了更好的学习本课程,本节带你回顾ServiceComb的开发流程,如果想更加详细的学习Apache ServiceComb开发方法请参考本系列的ServiceComb课程。
2.1什么是ServiceComb
ServiceComb是华为2017年开源的微服务框架,ServiceComb在华为内部的实践中沉淀了丰富的企业级应用开发 经验,该项目已于2017年12月进入Apache孵化器。
Apache ServiceComb官网地址在http://servicecomb.incubator.apache.org/cn/。
ServiceComb相比SpringCloud的优势有什么?
1、ServiceComb支持的通信协议比SpringCloud多ServiceComb支持多种通信协议, Rest、Highway(RPC)等SpringCloud仅支持Rest。
2、相比SpringCloud的Rest协议,Highway(RPC)协议性能更高,Highway是基于二进制的序列化方式传输数据,采用二进制编码的系统的性能远高于采用文本的HTTP协议。
3、ServiceComb的商业版本CSE相比SpringCloud不仅提供了微服务开发框架,还提供了微服务云部署,管理、治 理等一站式解决方案。
2.2注册中心
服务中心是微服务框架中的重要组件,用于服务元数据以及服务实例元数据的管理和处理注册、发现。服务中心与 微服务提供/消费者的逻辑关系下图所示:
1、安装注册中心
提供windows、linux版本安装
windows: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
linux: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
本教程开发环境使用windows版本的注册中心。
2、启动方式
提供可执行文件启动,以Docker的方式运行
本教程开发环境使用启动可执行文件,进入安装程序的解压目录:
start-service-center.bat 注册中心
start-frontend.bat 注册中心前端
默认http://127.0.0.1:30103为注册中心前端地址:
2.3服务提供方
2.3.1需求分析
本案例接口调用关系如下图:
1、客户端请求helloworld-consumer服务,传入参数name
2、helloworld-consumer服务请求helloworld-provider得到student
3、helloworld-consumer服务将student响应给客户端
2.3.2创建SpringBoot工程
本案例基于SpringBoot进行构建,ServiceComb提供spring-boot-starter-provider、spring-boot-starter- transport等与springboot的整合包。
导入本案例工程结构,如下:
工程介绍如下:
1、helloworld-model 模型工程
管理所用到模型类,如student等。
2、helloworld-api 接口工程管理所有的服务接口。
3、helloworld-provider服务提供方
定义接口实现提供方。
4、helloworld-consumer服务消费方服务接口调用方。
2.3.3引入依赖
1、java-chassis-dependencies依赖管理
向微服务工程添加 ServiceComb的JAVA SDK包依赖,为了控制依赖版本在父工程添加 依赖管理,如下:
<dependency>
<groupId>org.apache.servicecomb</groupId>
<artifactId>java‐chassis‐dependencies</artifactId>
<version>${servicecomb.java‐chassis.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
完整的父工程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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‐boot‐starter‐parent</artifactId>
<version>1.5.9.RELEASE</version>
</parent>
<groupId>com.itheima</groupId>
<artifactId>test‐servicecomb</artifactId>
<packaging>pom</packaging>
<version>1.0‐SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
<tomcat.version>8.5.28</tomcat.version>
<spring‐boot.version>1.5.9.RELEASE</spring‐boot.version>
<springframework.version>4.3.13.RELEASE</springframework.version>
<mybatis‐spring‐boot.version>1.3.1</mybatis‐spring‐boot.version>
<mybatis.version>3.4.5</mybatis.version>
<druid.version>1.1.6</druid.version>
<mysql‐connector‐java.version>5.1.45</mysql‐connector‐java.version>
<commons‐io.version>2.6</commons‐io.version>
<org.apache.commons.io.version>1.3.2</org.apache.commons.io.version>
<commons‐fileupload.version>1.3.3</commons‐fileupload.version>
<commons‐codec.version>1.10</commons‐codec.version>
<commons‐lang3.version>3.6</commons‐lang3.version>
<okhttp.version>3.9.1</okhttp.version>
<lombok.version>1.16.16</lombok.version>
<mysql‐connector‐java.version>5.1.40</mysql‐connector‐java.version>
<servicecomb.java‐chassis.version>1.0.0‐m2</servicecomb.java‐chassis.version>
</properties>
<!‐‐test‐‐>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.servicecomb</groupId>
<artifactId>java‐chassis‐dependencies</artifactId>
<version>${servicecomb.java‐chassis.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql‐connector‐java</artifactId>
<version>${mysql‐connector‐java.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis‐spring‐boot‐starter</artifactId>
<version>${mybatis‐spring‐boot.version}</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper‐spring‐boot‐starter</artifactId>
<version>1.2.4</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<dependency>
<groupId>commons‐io</groupId>
<artifactId>commons‐io</artifactId>
<version>${commons‐io.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons‐io</artifactId>
<version>${org.apache.commons.io.version}</version>
</dependency>
<dependency>
<groupId>commons‐fileupload</groupId>
<artifactId>commons‐fileupload</artifactId>
<version>${commons‐fileupload.version}</version>
</dependency>
<dependency>
<groupId>commons‐codec</groupId>
<artifactId>commons‐codec</artifactId>
<version>${commons‐codec.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons‐lang3</artifactId>
<version>${commons‐lang3.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<!‐‐ java编译插件 ‐‐>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven‐compiler‐plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF‐8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
2、向helloworld-provider添加依赖
<dependencies>
<dependency>
<groupId>com.itheima</groupId>
<artifactId>helloworld‐api</artifactId>
<version>1.0‐SNAPSHOT</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.hibernate</groupId>
<artifactId>hibernate‐validator</artifactId>
</dependency>
</dependencies>
其中引入spring-boot-starter-provider表示启用java chassis的核心功能,用于“JAVA应用方式”和”Web开发方式“开发。
2.3.4接口定义
ServiceComb基于OpenAPI规范定义服务契约,契约即接口契约是服务端和消费端之间的接口定义,ServiceComb
支持Swagger注解方式定义接口契约。
(OpenAPI是Apache下的项目,它定义一种用来描述API格式或API定义的语言来规范RESTful服务开发过程,
Swagger是基于OpenAPI规范定义接口的套工具集)
1、接口定义
在helloworld-api工程定义接口:
public interface HelloWorldInterface {
Student hello(String name);
}
在helloworld-provider定义接口,接口定义采用springmvc方式,定义接口需指定schemaId,schemaId必须保证微服务范围内唯一。
@RestSchema(schemaId="helloworld")
@RequestMapping("/")
public class HelloWorldController implements HelloWorldInterface {
@GetMapping(path = "hello")
@Override
public Student hello(String name) {
Student student = new Student();
student.setName(name);
student.setAddress("北京");
return student;
}
}
注意:
1.通过RestSchema替换RestController
2.需要显示声明@RequestMapping
2.3.5服务描述配置
在src/main/resources下定义microservice.yaml:
APPLICATION_ID: helloworldproject
service_description:
name: helloworld‐provider version: 1.0.0
servicecomb:
rest:
address: 0.0.0.0:8080 service:
registry:
address: http://127.0.0.1:30100
配置说明:
APPLICATION_ID:项目名/应用名
service_description.name:微服务名
version: 微服务版本
servicecomb.rest.address:
0.0.0.0:8080:接口对外暴露的端口
ervicecomb.rest.service.registry.address:
http://127.0.0.1:30100:注册中心的地址
2.3.6启动类
@EnableServiceComb @SpringBootApplication
public class HelloWorldProviderApplication { public static void main(String[] args) {
SpringApplication.run(HelloWorldProviderApplication.class);
}
}
@EnableServiceComb:启用java.chassis核心功能。
@SpringBootApplication:springBoot提供的注解,实现包扫描、自动配置。
2.3.7测试
启动成功,观察服务在注册中心是否注册成功
在浏览器输入http://localhost:8080/hello?name=%E9%BB%91%E9%A9%AC
输出如下:
{"name":"黑马","age":0,"address":"北京","birthday":null}
2.4服务消费方
2.4.1引入依赖
在helloworld-consumer工程引入如下依赖:
<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.hibernate</groupId>
<artifactId>hibernate‐validator</artifactId>
</dependency>
完整的代码如下:
<?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>test‐servicecomb</artifactId>
<groupId>com.itheima</groupId>
<version>1.0‐SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>helloworld‐consumer</artifactId>
<dependencies>
<dependency>
<groupId>com.itheima</groupId>
<artifactId>helloworld‐api</artifactId>
<version>1.0‐SNAPSHOT</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.hibernate</groupId>
<artifactId>hibernate‐validator</artifactId>
</dependency>
</dependencies>
</project>
2.4.2服务调用
ServiceComb提供RestTemplate、AsynRestTemplate、透明RPC方式调用服务接口。RestTemplate:
RestTemplate是Spring提供的RESTful访问接口,ServiceComb提供该接口的实现类用于服务的调用。
AsynRestTemplate:
AsyncRestTemplate 开发方式允许用户异步的进行服务调用。具体的业务流程和 restTemplate 类似,只是这里以异步的形式进行服务的调用。
透明RPC方式:
透明RPC开发模式允许用户通过简单的java interface像本地调用一样进行服务调用。透明RPC模式之所以说透明, 是因为它与服务接口使用的什么协议无关,与服务接口的开发方式无法(使用SpringMVC方式、RPC/Jax-RS),所以在实例开发中更推荐使用透明RPC方式。
采用透明PRC方式向服务调用controller中注入接口代理对象:
@RpcReference(microserviceName="helloworld‐provider",schemaId="helloworld")
HelloWorldInterface helloWorldInterface;
此代理对象将从注册中心查找helloworld服务提供方地址,进行调用。
完整的服务调用代码如下:
@RestSchema(schemaId="helloworldConsumer") @RequestMapping("/")
public class HelloWorldConsumerController {
@RpcReference(microserviceName="helloworld‐provider",schemaId="helloworld")
HelloWorldInterface helloWorldInterface;
@GetMapping(path = "request")
public Student request(String name){
return helloWorldInterface.hello(name);
}
}
2.4.3服务描述配置
内容格式与服务提供方大致相同,内容如下:
APPLICATION_ID: helloworldproject service_description:
name: helloworld‐consumer version: 1.0.0
servicecomb:
rest:
address: 0.0.0.0:8081 service:
registry:
address: http://127.0.0.1:30100
2.4.4启动类
@EnableServiceComb @SpringBootApplication
public class HelloWorldConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(HelloWorldConsumerApplication.class);
}
}
2.4.5测试
客户端请求服务消费方,服务消费方请求服务提供方。
浏览器请求:http://localhost:8081/request?name=黑马 http://localhost:8081/request:是服务消费方的地址
输出:
{"name":"黑马","age":0,"address":"北京","birthday":null}