开发第一个微服务应用
准备工作
在开发第一个Java-Chassis微服务之前,请先确保本地开发环境已经准备就绪,参考安装本地开发环境。
运行这些例子之前,需要先安装注册中心 和配置中心 。华为云提供一个出色的本地轻量化微服务引擎 , 可以直接下载安装使用,它包含了注册中心和配置中心。
Java Chassis依赖于Spring Boot,如果对于Spring Boot比较陌生,可以先通过 Spring Boot入门 了解。
例子介绍
Basic示例 包含了3个微服务: gateway, provider, consumer。 这3个服务完成了一个最简单的微服务架构。 其中 provider 提供一个 REST 接口, consumer 调用 provider 的 REST 接口完成同样的功能。 gateway 作为微服务的接入端, 负责所有外部请求的接入。
如果已经了解 JAVA + MAVEN 应用程序开发, 可以直接下载并运行这个示例。 下面介绍该示例的关键开发步骤。
开发一个带 REST 接口的微服务
配置pom文件
创建一个空的maven工程。建议先配置dependencyManagement
来管理依赖项
<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>
依赖项需要引入solution-basic
, 并且引入注册中心、配置中心和Logger系统的依赖
<dependencies>
<dependency>
<groupId>org.apache.servicecomb</groupId>
<artifactId>solution-basic</artifactId>
</dependency>
<!-- using log4j2 -->
<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>
<!-- using service-center & kie -->
<dependency>
<groupId>org.apache.servicecomb</groupId>
<artifactId>registry-service-center</artifactId>
</dependency>
<dependency>
<groupId>org.apache.servicecomb</groupId>
<artifactId>config-kie</artifactId>
</dependency>
<!-- using java chassis http transport -->
<dependency>
<groupId>org.apache.servicecomb</groupId>
<artifactId>java-chassis-spring-boot-starter-standalone</artifactId>
</dependency>
</dependencies>
solution-basic
中已经包含了常见场景下开发Java-Chassis微服务所需的全部依赖项。
引入maven-compiler-plugin
插件,使项目打包时保留方法参数名:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<compilerArgument>-parameters</compilerArgument>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
添加配置文件
按照Spring Boot应用程序要求,增加 application.yaml
文件 ,存放在resources
目录中。
文件内容如下,这份文件表示当前开发的是basic-application
应用下的名为provider
的微服务,版本为0.0.1。该微服务连接的注册中心地址为http://localhost:30100
,配置中心地址为http://localhost:30110
。 该微服务监听HTTP协议的9093
端口。
servicecomb:
service:
application: basic-application
name: provider
version: 0.0.1
rest:
address: 0.0.0.0:9093
# 注册发现
registry:
sc:
address: http://localhost:30100
# 动态配置
kie:
serverUri: http://localhost:30110
编写启动类
Java Chassis应用是一个标准的Spring Boot应用。本示例中,设置 WebApplicationType.NONE
, 这样会使用 Java Chassis自带的高性能 HTTP 容器,而不使用 Spring
Boot自带的WEB容器。
@SpringBootApplication
public class ProviderApplication {
public static void main(String[] args) throws Exception {
try {
new SpringApplicationBuilder()
.web(WebApplicationType.NONE)
.sources(ProviderApplication.class)
.run(args);
} catch (Exception e) {
e.printStackTrace();
}
}
}
编写服务
本例子采用契约优先的开发方法。
首先定义服务接口:
@RequestMapping(path = "/provider")
public interface ProviderService {
@GetMapping("/sayHello")
String sayHello(@RequestParam("name") String name);
@GetMapping("/exampleConfig")
String exampleConfig();
}
在工程中添加一个REST接口类用于接收请求:
@RestSchema(schemaId = "ProviderController", schemaInterface = ProviderService.class)
public class ProviderController implements ProviderService {
private DynamicProperties dynamicProperties;
private String example;
@Autowired
public ProviderController(DynamicProperties dynamicProperties) {
this.dynamicProperties = dynamicProperties;
this.example = this.dynamicProperties.getStringProperty("basic.example",
value -> this.example = value, "not set");
}
@Override
public String sayHello(String name) {
return "Hello " + name;
}
@Override
public String exampleConfig() {
return example;
}
}
该类实现了两个REST接口,其中sayHello
实现了一个简单的echo程序;exampleConfig
演示了如何通过配置中心下发配置项,并动态监听配置项的变化。
添加日志配置文件
本例子引入了log4j2组件。如果想要看到运行日志,还需要手动添加一份日志配置文件,文件存放位置为resources\log4j2.xml
,内容如下:
<Configuration status="INFO">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="[%d][%t][%p]%m [%c:%L]%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="INFO">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
调用服务
在 Consumer 里面,演示了如何调用 Provider 的服务。 首先声明一个 PRC 接口的 Bean。
@Configuration
public class ProviderServiceConfiguration {
@Bean
public ProviderService providerService() {
return Invoker.createProxy("provider", "ProviderController", ProviderService.class);
}
}
使用 @Autowired 声明 RPC 接口的远程引用, 然后可以像调用本地方法一样,访问 Provider 的服务。
@RestSchema(schemaId = "ConsumerController", schemaInterface = ConsumerService.class)
public class ConsumerController implements ConsumerService {
private ProviderService providerService;
@Autowired
public void setProviderService(ProviderService providerService) {
this.providerService = providerService;
}
@Override
public String sayHello(String name) {
return providerService.sayHello(name);
}
@Override
public String exampleConfig() {
return providerService.exampleConfig();
}
}
微服务网关
微服务网关是一个普通的微服务,需要额外引入 edge-core
。
<dependency>
<groupId>org.apache.servicecomb</groupId>
<artifactId>edge-core</artifactId>
</dependency>
启动服务
依次启动 ProviderApplication
、ConsumerApplication
和GatewayApplication
, 访问 http://localhost:9090/sayHello?name=World
,可以得到响应"Hello World!"
。
打开注册中心、配置中心控制台,还可以看到微服务的实例列表。通过配置中心给 ProviderApplication
添加配置, 访问 http://localhost:9090/exampleConfig
,
可以得到响应,响应包含了最新的配置项的值。
使用Nacos
注册中心和配置中心
本例子还可以使用 Nacos
作为注册中心和配置中心。
编译:
mvn clean install -Pnacos
运行:
java -Dspring.profiles.active=nacos -jar basic-provider-2.0-SNAPSHOT.jar
也可以在IDE里面选择 MAVEN 的 nacos PROFILE,并修改 application.yml 的 spring.profiles.active
为 nacos.