微服务作为消除软件组件之间隐藏的依赖关系并允许细粒度部署而不拖拽不必要的上下文的方式已经变得流行。通过这种方式,微服务可以促进敏捷开发团队的自主性,并允许应用程序更自然地发展,并在某些情况下更快地开发。
我喜欢Java,所以我将向您展示一个为JVM开发微服务的过程和框架。这是一系列文章的第一部分,介绍了端到端的服务开发。在我们将来的文章中讨论更具体的细节之前,第一篇文章(第1部分)将介绍一些基本方面。第2部分将介绍Swagger规范中的代码生成,之后的文章将深入介绍实现良好服务的一些功能。
微服务特性
微服务的特征由James Lewis和Martin Fowler定义。我们可以总结一下技术特征:
- 单个运行时可执行文件 - 消除运行时库依赖性和对运行时容器打包的依赖性。
- 定义良好的API,支持单个有用的业务功能。
- 用于健康监控和记录的标准接口,便于管理大量独立服务
- 在Spring平台中,以下库支持这些特性:
- Spring Boot提供了单一的可执行特性,它为每个微服务提供了自己的HTTP堆栈(遗憾的是,这些内存占用了一些成本)并允许每个服务独立部署和管理。
- 使用Swagger的“合同优先”开发支持业务功能(有关此内容的更多信息,请参阅下一节)。
- Spring Actuator支持健康监测
- Sleuth支持标准化日志记录
合同优先发展
微服务应该提供单一有用的业务功能。这里有一些细微差别,可以归结为一个微服务,代表其API表示中的抽象业务级别。微服务应该从基础技术细节(例如数据模式或实现细节)中抽象出服务的使用者。抽象允许服务实现发展,同时对消费者的干扰最小。
API设计中常见的反模式是从实现开始,然后生成API规范 - “点击优先”方法。由此产生的接口往往过于技术化,“开发人员充满敌意”,并与实现细节紧密结合。
更好的模式是首先与消费者和其他利益相关者合作设计服务API。然后可以在负责服务实现,消费者实现,测试等的不同开发团队之间共享API规范。
对于此服务,我们将使用Swagger设计REST-ish API,但原理和技术与我们是否为REST-ish无关。例如,可以使用protocol buffers或其他接口规范工具轻松设计RPC样式服务。
我们发现在自己的git存储库中管理API规范是有益的,与服务实现分开。好处包括:
- 由于我们只有API规范,因此在审核后可轻松容纳更改。
- 服务实现者和消费者可以并行地开始他们的开发工作,从而增加团队自治并减少跨团队依赖性。
- 为服务使用者提供测试服务模拟的能力。
让我们将流程分为以下几个步骤:
- 设置服务接口项目。
- 在Swagger文件中定义服务规范并生成代码存根。
- 设置使用生成的代码存根的服务实现项目。
服务接口
我们将构建一个简单的Hello World服务,该服务使用GET方法公开/ greeting资源,该方法在调用时以包含“Hello World”消息字符串的JSON有效负载进行响应。
首先创建一个名为api-helloworld-v1-interface的Hello World Interface项目。项目结构符合标准的maven项目结构。
pom.xml文件包含以下库的依赖项:
- Swagger Codegen Maven插件,用于根据Swagger规范构建服务器存根
- 用于拉出实现JAX-RS规范的CXF模块的Apache CXF依赖项
- JSON编组和解组的Jackson JSON Provider依赖项使用了JAX-RS。提供程序通过JAX-RS自动注册
- Spring Boot依赖和
- PojoBuilder为JSON序列化构建支持POJO。
完整的pom.xml文件在这里可用,但主要的兴趣在于Swagger Codegen插件的配置。
的pom.xml
<plugins> <plugin> <groupId>io.swagger</groupId> <artifactId>swagger-codegen-maven-plugin</artifactId> <version>2.2.2</version> <executions> <execution> <id>generate-client-jar</id> <phase>generate-sources</phase> <goals> <goal>generate</goal> </goals> <configuration> <inputSpec>src/main/resources/swagger.yml</inputSpec> <templateDirectory>src/main/resources/swagger-codegen-templates/jaxrs-cxf</templateDirectory> <language>jaxrs-cxf</language> <configOptions> <sourceFolder>src/gen/java</sourceFolder> <apiPackage>${swagger-gen.api.package}</apiPackage> <modelPackage>${swagger-gen.model.package}</modelPackage> <serializableModel>true</serializableModel> <useJaxbAnnotations>false</useJaxbAnnotations> <dateLibrary>java8</dateLibrary> </configOptions> </configuration> </execution> <execution> <id>generate-html</id> <phase>generate-sources</phase> <goals> <goal>generate</goal> </goals> <configuration> <inputSpec>src/main/resources/swagger.yml</inputSpec> <language>html</language> </configuration> </execution> </executions> </plugin> </plugins>
我们的Swagger Codegen插件配置为两个执行任务:
- 生成代码存根,包括服务器端代码,客户端代码和模型POJO,
- 生成HTML文档。
对于代码生成,我们将输入规范提供为文件src / main / resources / swagger.yml。代码生成模板在文件夹src / main / resources / swagger-codegen-templates / jaxrs-cxf中提供。这些模板使用Mustache语法生成以下代码存根:
API:
代码gen插件使用此模板来定义Java接口。生成的Java接口在swagger规范中定义的每个operationId包含一个方法,该规范使用相应的HTTP方法,请求/响应媒体类型,查询参数,头参数,主体参数和表单参数进行注释。 swagger规范的tags:字段构成了以Api为后缀的Java接口名称的一部分
API实现:
如apiImpl.mustache文件中所指定,此模板生成API的存根实现。
模型POJO:
为Swagger规范中指定的每个对象生成POJO
正文参数:
将输入参数添加到生成的API方法中,这些API方法在API规范中定义为:body
我们使用代码生成语言作为jaxrs-cxf,因为CXF提供了一种使用HTTP绑定通过Annotations构建RESTFul服务的标准方法。
HTML生成非常简单,只需将输入规范指定为swagger.yml文件,将HTML指定为输出语言即可。
package-info.java
这为包级别文档和包级别注释提供了一个主页。
package com.example.api.hello.v1.model;
你好,client.yml
保存要与界面一起提供的可配置属性。
hello.endpoint:http:// localhost:8090 / api / v1 / hello
下一步
这篇文章讨论了我们可以用来开发Java和Spring中的微服务的工具的一些基本原理。我们已经审查了服务接口的项目设置和结构。在本系列的下一部分中,我们将讨论Swagger API定义并查看源代码生成过程。
Tags
最新内容
- 1 day 5 hours ago
- 1 day 7 hours ago
- 1 day 8 hours ago
- 3 days 23 hours ago
- 4 days 7 hours ago
- 4 days 7 hours ago
- 4 days 8 hours ago
- 4 days 8 hours ago
- 1 week 1 day ago
- 1 week 1 day ago