在Spring Boot中使用华为云微服务CSE

概述

 

Spring Boot可以让开发者能够更加快速的构建Spring应用。主要提供了如下功能:

  1. 创建独立可执行的Spring应用。通过将应用程序打包为jar,就可以通过java -jar来执行应用程序。

  2. 内嵌Tomcat, Jetty等WEB服务器,而不需要开发者打包war。

  3. 提供starter简化maven依赖关系配置。

将Spring Boot用于微服务开发,可以极大的简化开发者配置和部署。CSE提供了完善的的服务治理能力、良好的跨语言特性和高效的异步通信能力,通过使用CSE,可以快速启用各种满足商业运维需要的功能。基于Spring Boot 2.0的IoT应用集成和使用CSE实践提供了一个实际的例子,描述了Spring Boot中集成CSE框架带来的变化,以及演示 了部分开箱即用的治理功能。CSE同时支持集成Spring Boot 1和Spring Boot 2,在前面的章节中,主要介绍Spring Boot 1,两者集成的原理和步骤基本是一致的,在最后的章节,会描述使用Spring Boot 2的差异。

开发者通常会以如下几种方式使用Spring Boot:

  1. JAVA应用方式:引入spring-boot-starter,开发普通JAVA应用。该应用不会启动WEB服务器。

  2. Web开发方式:引入spring-boot-starter-web,开发Web应用。该应用会包含一个内嵌的Tomcat或者Jetty服务器,并且使用The Spring Web MVC framework(简称Spring MVC)开发REST接口。

在两种情况下,都可以集成CSE,原理图如下:

  • JAVA应用方式

这种集成方式相对简单,相当于直接将CSE通过Spring Boot应用拉起,不涉及任何改造和变化。

  • Web开发方式

该集成方式的本质是将Spring MVC的DispatcherServlet替换为CSE的RestServlet。

 

CSE提供的组件说明

 

针对Spring Boot、Spring Cloud,提供了如下几个组件:

  • spring-boot-starter-configuration

接入配置中心。当需要在Spring Boot、Spring Cloud应用中,使用配置中心作为动态配置管理工具的时候,需要依赖。

  • spring-boot-starter-registry

接入服务中心。当需要在Spring Boot、Spring Cloud应用中,使用服务中心作为服务注册、发现管理工具的时候,需要依赖。

  • spring-boot-starter-discovery

适配Spring Cloud的DiscoveryClient接口。当在Spring Cloud中使用@EnableDiscoveryClient时,需要依赖。

  • spring-boot-starter-provider

在Spring Boot中通过@EnableServiceComb启用CSE的核心功能。这个功能可以用于“JAVA应用方式”和”Web开发方式“。 在”Web开发方式”中,通过spring.main.web-environment=false禁用了Web环境。因此,这个模块主要是解决”JAVA应用方式“的问题。

  • spring-boot-starter-transport

在Spring Boot中通过@EnableServiceComb启用CSE的核心功能,并启用CSE的RestServlet。用于” Web开发方式“。

开发过程中会使用到的组件是spring-boot-starter-provider和spring-boot-starter-transport,详细使用场景会在后面的章节说明。

 

JAVA应用方式开发步骤

 

使用JAVA方式集成,为Spring Boot应用增加了一个高效的HTTP服务器和REST开发框架。这种方式集成非常简单。只需要在项目中引入相关依赖,并且使用@EnableServiceComb标签即可。

项目代码示例参考:

https://github.com/huawei-microservice-demo/SpringCloudIntegration/blob/master/spring-boot-simple

  • 引入依赖

依赖关系中增加spring-boot-starter-provider,即可引入CSE的核心功能。cse-solution-service-engine增加了接入华为公有云相关的认证模块和治理相关模块,并排除了log4j运行时包,防止和spring boot缺省携带的logback冲突。引入hibernate-validator的目的是spring boot会检测validation-api的实现类,检测不到会无法启动。


    
        
            com.huawei.paas.cse
            cse-dependency
            2.3.12
            pom
            import
        
    



    
        org.apache.servicecomb
        spring-boot-starter-provider
    
    
        com.huawei.paas.cse
        cse-solution-service-engine
        
            
                org.slf4j
                slf4j-log4j12
            
        
    
    
        org.springframework.boot
        spring-boot-starter
    
    
        org.hibernate
        hibernate-validator
    

  • 启用CSE的核心功能

在启动类前面增加@EnableServiceComb即可。

@SpringBootApplication
@EnableServiceComb
public class WebsiteMain {
    public static void main(final String[] args) {
        SpringApplication.run(WebsiteMain.class, args);
    }
}

通过以上配置,就可以完整使用CSE提供的所有功能,使用CSE开发REST服务,并开启各种治理功能。

  • 配置微服务

通过microservice.yaml文件可以定制微服务的信息,包括应用名称、微服务名称、监听的地址和端口等。

集成CSE后,可以通过CSE的方式开发REST接口:

@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;
    }
}

然后可以通过:http://localhost:9093/hello?name=world来访问。

 

Web开发方式开发步骤

 

Web开发方式和JAVA应用方式的开发步骤基本类似。示例代码参考:

https://github.com/huawei-microservice-demo/SpringCloudIntegration/blob/master/spring-boot-web

主要有如下区别:

  • JAVA应用方式基于spring-boot-starter,而Web开发方式基于spring-boot-starter-web。

  • JAVA应用方式依赖spring-boot-starter-provider,而Web开发方式依赖spring-boot-starter-transport。spring-boot-starter-web已经携带了hibernate-validator,不需要额外依赖。

  • 在启动函数中,Web开发方式可以通过声明

@SpringBootApplication(exclude=DispatcherServletAutoConfiguration.class)

来关闭org.springframework.web.servlet.DispatcherServlet,通过@EnableServiceComb会启用org.apache.servicecomb.transport.rest.servlet.RestServlet。虽然排除DispatcherServlet不是必须的,但是大多数场景一个微服务里面存在多个REST框架都不是很好的主意,会造成很多使用上的误解。

  • 在microservice.yaml文件中通过配置项servicecomb.rest.servlet.urlPattern来指定RestServlet的URL根路径。并且配置项cse.rest.address里面的监听端口,必须和tomcat监听的端口保持一致(默认是8080,可以通过application.yml中增加server.port修改)

集成CSE后,可以通过CSE的方式开发REST接口:

@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;
    }
}

然后可以通过:http://localhost:9093/servicecomb/rest/hello?name=world 来访问。其中/servicecomb/rest是配置文件中指定的URI,可以设置为/。

可以看到使用的标签和Spring MVC大部分是一样的。但也有少量不一样的地方,比如:

  1. 通过RestSchema替换RestController

  2. 需要显示声明@RequestMapping

如果业务代码不是新开发,而是基于Spring MVC做的开发,现在基于CSE做改造,还需要注意在禁用DispatcherServlet后,和其有关的功能特性将不再生效。

在下面的章节,还会详细介绍在Spring MVC模式下两者的区别。

 

JAVA应用方式和Web开发方式的区别

 

两种开发方式都会启用CSE的全量功能,JAVA应用方式运行于独立的HTTP服务器(基于vert.x构建)上,性能上存在很大的优势。Web开发方式运行于Tomcat或者其他内置的Web服务器之上,作为一个Servlet接收请求,因此在开发过程中,可以使用Web容器提供的一些功能,比如提供页面服务,使用Filter等。当应用只需要提供REST服务,并且对性能要求很高的场景,建议使用JAVA应用方式。

 

Spring MVC模式的差异

 

CSE支持使用Spring MVC提供的标签(org.springframework.web.bind.annotation)来声明REST接口,但是两者是独立的实现,而且有不一样的设计目标。CSE的目标是提供跨语言、支持多通信协议的框架,因此去掉了Spring MVC中一些对跨语言支持不是很好的特性,也不支持特定运行框架强相关的特性,比如直接访问Servlet协议定义的HttpServletRequest。下面是一些显著的差别。

  • 服务声明方式

Spring MVC使用@RestController声明服务,而CSE使用@RestSchema声明服务,并且需要显示的使用@RequestMapping声明服务路径,以区分该服务是采用Spring MVC的标签还是使用JAX RS的标签。

@RestSchema(schemaId = "hello")
@RequestMapping(path = "/")

Schema是CSE的服务契约,是服务运行时的基础,服务治理、编解码等都基于契约进行。在跨语言的场景,契约也定义了不同语言能够同时理解的部分。

  • 数据类型支持

采用Spring MVC,可以在服务定义中使用多种数据类型,只要这种数据类型能够被json序列化和反序列化。比如:

// 抽象类型
public void postData(@RequestBody Object data)
// 接口定义
public void postData(@RequestBody IPerson interfaceData)
// 没指定类型的泛型
public void postData(@RequestBody Map rawData)
// 具体协议相关的类型
public void postData(HttpServletRequest rquest)

上面的类型在CSE都不提供支持。因为CSE会根据接口定义生成契约,从上面的接口定义,如果不结合实际的实现代码或者额外的开发文档说明,无法直接生成契约。也就是站在浏览器的REST视角,不知道如何在body里面构造消息内容。

为了支持快速开发,CSE的数据类型限制也在不停的扩充,比如支持HttpServletRequest,但是实际在使用的时候,他们与WEB服务器的语义是不一样的,比如不能直接操作流。因此建议开发者在CSE的使用场景下,尽可能使用契约能够描述的类型,让代码阅读性更好。

CSE在数据类型的支持方面的更多说明,请参考: https://java.huaweicse.com/build-provider/interface-constraints.html

  • 常用标签支持

下面是CSE对于Spring MVC常用标签的支持情况。

标签名称 是否支持 说明
RequestMapping  
GetMapping  
PutMapping  
PostMapping  
DeleteMapping  
PatchMapping  
RequestParam  
CookieValue  
PathVariable  
RequestHeader  
RequestBody 目前支持application/json,plain/text
RequestPart 用于文件上传的场景,对应的标签还有Part、MultipartFile
ResponseBody 返回值缺省都是在body返回
ResponseStatus 可以通过ApiResponse指定返回的错误码
RequestAttribute Servlet协议相关的标签
SessionAttribute Servlet协议相关的标签
MatrixVariable  
ModelAttribute  
ControllerAdvice  
CrossOrigin  
ExceptionHandler

 

InitBinder  
  • 其他

CSE不支持在GET方法中使用POJO对象进行参数映射

比如:public void getOperation(Person p)

CSE不支持在GET方法中使用Map映射所有可能的参数

比如:public void getOperation(Map p)

 

使用Spring Boot 2

 

说明:需要使用CSE SDK 2.3.51及其以上版本

针对Spring技术体系,CSE提供了如下几个组件,方便开发者。

  • cse-dependency 这个依赖关系管理器提供CSE推荐的依赖关系管理。它的依赖关系会随着CSE版本的发展进行调整。比如在spring 4是稳定版本的时候,这个管理器提供spring 4的依赖;spring 5是稳定版本的时候,这个管理器提供spring 5的依赖。当前CSE提供的版本默认为spring 4.

    • spring4升级到spring 5的注意事项
      • spring 5和spring 4在很多接口和使用方法上是不兼容的。因此CSE针对这些不兼容的实现提供了对应的处理措施。比如:EnableServiceComb:spring 4为org.apache.servicecomb.springboot.starter.provider.EnableServiceComb, spring 5为org.apache.servicecomb.springboot2.starter.EnableServiceComb; DispatcherServletAutoConfiguration: spring 4为org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration, spring5为org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration。
      • spring 5废弃了AsyncRestTemplate。CSE提供了AsyncRestTemplate的实现,因此也废弃这个使用方式。
      • 如果使用了bean配置文件,并且定义了如下schema,需要调整:xsi:schemaLocation="http://www.springframework.org/schema/beansclasspath:org/springframework/beans/factory/xml/spring-beans-3.0.xsd” 修改为:xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd“
  • cse-dependency-spring4

如果业务代码没使用spring 5或者spring boot 2,可以使用这个管理器。

  • cse-dependency-spring5

如果业务代码使用spring 5,可以使用这个管理器。

  • cse-dependency-spring-boot1

如果业务代码使用spring boot 1和spring 4,可以使用这个管理器。

  • cse-dependency-spring-boot2

如果业务代码使用spring boot 2和spring 5,可以使用这个管理器。

如何使用

开发者可以利用maven提供的dependencyManagement更好的管理依赖关系。


    
        
            com.huawei.paas.cse
            cse-dependency
            ${paas.cse.version}
            pom
            import
        
    

  • CSE 支持spring 4/5 以及spring boot 1/2 maven组件依赖关系配置参考提供了配置和原理说明。

  • 基于Spring Boot 2.0的IoT应用集成和使用CSE实践提供了一个实际Spring Boot 2的例子。

 

了解更多

开发者可以通过微服务引擎华为云官网了解CSE。在CSE帮助中心可以获取更多产品信息,如有疑问,可通过CSE论坛进行咨询。

 

 

你可能感兴趣的:(微服务)