ServiceComb和CSE的微服务打包方式

以standalone模式打包

一个Standalone的容器,以简单的Main加载Spring启动,因为服务通常不需要Tomcat/JBoss等Web容器的特性,没必要用Web容器去加载服务。微框架提供了standalone部署运行模式,服务容器只是一个简单的Main方法,并加载一个简单的Spring容器,用于暴露服务。

操作步骤

  • 步骤1 编写Main函数,初始化日志和加载服务配置,内容如下:
import org.apache.servicecomb.foundation.common.utils.BeanUtils;
import org.apache.servicecomb.foundation.common.utils.Log4jUtils;
public class MainServer {
public static void main(String[] args) throws Exception {
 Log4jUtils.init(); # 日志初始化
 BeanUtils.init();  # Spring bean初始化
 }
}
  • 步骤2 运行MainServer即可启动该微服务进程,向外暴露服务。

注意事项

如果使用的是rest网络通道,需要将pom中的transport改为使用cse-transport-rest-vertx包

以WEB容器模式打包

如果需要将该微服务加载到web容器中启动运行时,需要新建一个servlet工程包装一下,该servlet工程,根据需要,可以不写或写少量的引导代码即可。

开发示例

REST over Servlet对应使用web容器部署运行,需要新建一个servlet工程将微服务包装起来,打成war包,加载到web容器中启动运行。

对外发布的Path

当微服务部署到web容器中时,相对于独立运行,会涉及到web root以及servlet url pattern对url的改变。
对于传统开发框架而言,需要consumer感知对方的完整url;比如web root为/mywebapp,url pattern为/rest,业务级path为/application,则consumer代码必须通过/mywebapp/rest/application来访问。
这将导致一旦部署方式发生变化,比如从web容器变成standalone运行,则consumer或是producer必须修改代码来适配这个变化。

建议使用ServiceComb的部署解耦特性,无论是consumer,还是producer,在代码中都不要感知web root以及url pattern,这样ServiceComb在运行时,会自动适配producer实例的web root以及url pattern。

对于一些遗留系统改造,用户期望继续使用restTemplate.getForObject("cse://serviceName/mywebapp/rest/application"...),这个时候,用户必须将接口定义的path定位为: /mywebapp/rest/application,例如:

@RestSchema(schemaId = "test")
@RequestMapping(path = "/mywebapp/rest/application")

尽管如此,仍然推荐使用部署形态无关的方式来编码,可以减少后续由于部署形态变化,带来的修改代码问题。

maven依赖

<dependency>
    <groupId>org.apache.servicecomb</groupId>
    <artifactId>transport-rest-servlet</artifactId>
</dependency>

配置说明

与servlet机制配合,涉及到以下几个概念:

  • 启动spring context
    注意以下几种启动方式,是N选1的关系,不要同时使用。

    • 不使用springMVC的UI或RestController

      <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
           version="3.0">
      <context-param>
         <param-name>contextConfigLocation</param-name>
         <param-value>classpath*:META-INF/spring/*.bean.xml</param-value>
      </context-param>
      <listener>
         <listener-class>org.apache.servicecomb.transport.rest.servlet.RestServletContextListener</listener-class>
      </listener>
      </web-app>
      

      其中classpath:META-INF/spring/.bean.xml,无论任何情况,都可以不在contextConfigLocation中配置,因为ServiceComb机制会确保加载路径中包含它。
      这里仅仅是个示例,表示如果使用者需要定制contextConfigLocation,可以使用这个方法。

    • 使用springMVC的UI或RestController,且存在org.apache.servicecomb.transport.rest.servlet.CseDispatcherServlet

      <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
           version="3.0">
      <servlet>
        <servlet-name>SpringMVCServlet</servlet-name>
        <servlet-class>org.apache.servicecomb.transport.rest.servlet.CseDispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
        <servlet-name>SpringMVCServlet</servlet-name>
        <url-pattern>yourUrlPattern</url-pattern>
      </servlet-mapping>
      </web-app>
      

      注意:
      该servlet不是ServiceComb的处理入口,仅仅是UI或RestController的处理入口

    • 使用springMVC的UI或RestController,且不存在org.apache.servicecomb.transport.rest.servlet.CseDispatcherServlet
      需要继承springMVC的DispatcherServlet,再按CseDispatcherServlet的方式,配置自己的实现类
      @Override
      protected WebApplicationContext createWebApplicationContext(ApplicationContext parent){
      setContextClass(CseXmlWebApplicationContext.class);
      return super.createWebApplicationContext(parent);
      }
      
  • ServiceComb servlet
    url pattern根据业务自身规划设置即可,下面的/rest/仅仅是示例,不是固定值。
    url pattern必须以/\
    结尾
    以下两种声明方式也是多选一的关系,不要同时使用
    • 标准声明
      <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
           version="3.0">
      <servlet>
          <servlet-name>RestServlet</servlet-name>
          <servlet-class>org.apache.servicecomb.transport.rest.servlet.RestServlet</servlet-class>
          <load-on-startup>1</load-on-startup>
          <async-supported>true</async-supported>
      </servlet>
      <servlet-mapping>
          <servlet-name>RestServlet</servlet-name>
          <url-pattern>/rest/*</url-pattern>
      </servlet-mapping>
      </web-app>
      
    • 快捷声明
      在microservice.yaml文件中指定urlPattern,ServiceComb启动时会自动创建RestServlet,并设置相应的urlPattern:
      servicecomb.rest.servlet.urlPattern: /rest/*
      

典型场景配置示例

  • 纯ServiceComb,标准声明
    web.xml
    <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
           version="3.0">
      <listener>
          <listener-class>org.apache.servicecomb.transport.rest.servlet.RestServletContextListener</listener-class>
      </listener>
      <servlet>
          <servlet-name>RestServlet</servlet-name>
          <servlet-class>org.apache.servicecomb.transport.rest.servlet.RestServlet</servlet-class>
          <load-on-startup>1</load-on-startup>
          <async-supported>true</async-supported>
      </servlet>
      <servlet-mapping>
          <servlet-name>RestServlet</servlet-name>
          <url-pattern>/rest/*</url-pattern>
      </servlet-mapping>
    </web-app>
    
  • 纯ServiceComb,快捷声明
    web.xml:
    <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
           version="3.0">
      <listener>
          <listener-class>org.apache.servicecomb.transport.rest.servlet.RestServletContextListener</listener-class>
      </listener>
    </web-app>
    
    microservice.yaml:
    servicecomb.rest.servlet.urlPattern: /rest/*
    
  • springMVC UI或RestController接入请求,通过ServiceComb作为consumer发送到内部微服务
    web.xml:
    <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
           version="3.0">
      <servlet>
        <servlet-name>SpringMVCServlet</servlet-name>
        <servlet-class>org.apache.servicecomb.transport.rest.servlet.CseDispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
        <servlet-name>SpringMVCServlet</servlet-name>
        <url-pattern>yourUrlPattern</url-pattern>
      </servlet-mapping>
    </web-app>
    
    microservice.yaml:
    不配置servicecomb.rest.address以及servicecomb.rest.servlet.urlPattern
  • springMVC UI或RestController接入一些请求,同时通过ServiceComb接入另一些请求
    web.xml:
    <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
           version="3.0">
      <servlet>
        <servlet-name>SpringMVCServlet</servlet-name>
        <servlet-class>org.apache.servicecomb.transport.rest.servlet.CseDispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
        <servlet-name>SpringMVCServlet</servlet-name>
        <url-pattern>yourUrlPattern</url-pattern>
      </servlet-mapping>
    </web-app>
    
    microservice.yaml:
    servicecomb:
      rest:
        servlet:
          urlPattern: /rest/*
        address: 0.0.0.0:8080
    

    使用servlet filter注意事项

    RestServlet工作于异步模式,根据servlet 3.0的标准,整条工作链都必须是异步模式,所以,如果业务在这个流程上增加了servlet filter,也必须将它配置为异步:
    <filter>
    ......
    <async-supported>true</async-supported>
    </filter>
    

配置项

REST over Servlet在microservice.yaml文件中的配置项见表3-9。

表1-1 REST over Servlet配置项说明

配置项默认值取值范围是否必选含义注意
servicecomb.rest.address0.0.0.0:8080-服务监听地址必须配置为与web容器监听地址相同的地址
servicecomb.rest.server.timeout3000-超时时间单位为毫秒
servicecomb.rest.servlet.urlPattern 用于简化servlet+servlet mapping配置只有在web.xml中未配置servlet+servlet mapping时,才使用此配置项,配置格式为:/* 或 /path/*,其中path可以是多次目录

注意事项

Restful调用应该与web容器中其他静态资源调用(比如html、js等等)隔离开来,所以webroot后一段应该还有一层关键字,比如上面web.xml中举的例子(/test/rest)中的rest。

以tomcat为例,默认每个war包都有不同的webroot,这个webroot需要是basePath的前缀,比如webroot为test,则该微服务所有的契约都必须以/test打头。

当微服务加载在web容器中,并直接使用web容器开的http、https端口时,因为是使用的web容器的通信通道,所以需要满足web容器的规则。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值