REST 服务快速入门

微服务(SOFAStack MicroService)主要是通过 SOFARPC 来实现服务的发布和引用,而 SOFARPC 支持 REST 协议。本文以微服务本地开发到云端发布的整体流程为框架,让您了解如何在本地实现 SOFAREST 功能,以及如何将应用发布到云端,并在云端进行服务管控。本文主要讲述 SOFAREST 的实现原理,示例工程也支持直连的方式,让您在本地体验 SOFAREST 的服务发布和服务引用。

本地工程开发

SOFAREST 工程开发流程图

REST流程图.png

SOFAREST 示例代码演示视频

准备工作

  • 搭建 SOFABoot 环境。具体操作,请参见 搭建环境

  • 通过以下任一方式生成 2 个 SOFABoot Web 工程,分别作为服务发布方和引用方。

    • 创建 2 个 SOFABoot Web 工程。具体操作,请参见 新建工程

    • 直接下载 示例工程。下载后,请参考 版本说明将工程根目录下 pom.xml 文件中的版本号修改为最新版本号。

本地开发流程

  1. 引入依赖。

    按步骤创建的工程默认已经引入该依赖,请忽略此步骤;直接下载的示例工程需在 2 个本地 SOFABoot 工程 Web 模块 pom.xml 中引入 SOFARPC 的 Maven 依赖。

    <dependency>
        <groupId>com.alipay.sofa</groupId>
        <artifactId>rpc-enterprise-sofa-boot-starter</artifactId>
    </dependency>
  2. 编写业务逻辑。

    主要为服务发布和服务引用。本示例使用注解的方式配置 Bean,实现服务发布和引用。更多详情,请参见 使用注解方式。其它配置方式,请参见 使用 XML 配置使用编程 API

    • 服务发布的业务逻辑

      • 设计服务接口类

        本示例类名称为 SampleRestFacade.java,接口路径为 com.alipay.samples.rpc.SampleRestFacade

        @Path("/sofarest")  //注意该注解的继承性问题,实现类或方法中,该注解的缺失,可能会造成 SOFAREST 调用报 404 错误。
        @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
        @Produces(MediaType.APPLICATION_JSON +";charset=UTF-8")
        public interface SampleRestFacade{
            /**
            * http://localhost:8341/sofarest/hello
            */
            @GET
            @Path("/hello")
            public String hello();
        }
      • 编写服务实现类

        本示例类名称为 SampleRestFacadeImpl.java,接口实现路径为 com.alipay.samples.rpc.impl.SampleRestFacadeImpl

        @Service
        @SofaService(interfaceType =SampleRestFacade.class,bindings =@SofaServiceBinding(bindingType ="rest"))
        public class SampleRestFacadeImpl implements SampleRestFacade{
              private int count =0;
        
              public SampleRestFacadeImpl(){
                  System.out.println("print start");
              }
        
             @Override
             public String hello(){
                  return "Hello SOFARest! times = "+ count++;
             }
        }   
    • 服务引用逻辑

      • 引用对象注入

        本示例采用 ReferenceHolder 类对引用对象进行统一管理,示例如下:

        @Component
        public class ReferenceHolder{
              @SofaReference(interfaceType =SampleRestFacade.class, binding =@SofaReferenceBinding(bindingType ="rest",directUrl ="127.0.0.1:8341"))
              private SampleRestFacade sampleRestFacade;
              public SampleRestFacade getSampleRestFacade(){
                  return sampleRestFacade;
              }
             public void setSampleRestFacade(SampleRestFacade sampleRestFacade){
                 this.sampleRestFacade = sampleRestFacade;
             }
        }
        说明

        bindingType 为 rest 协议,直连 URL 端口为 8341,即 directUrl="127.0.0.1:8341"

      • 引用对象

        为了方便直观使用,本示例将引用服务逻辑放在了 myclient-app 工程 Web 模块的 com.alipay.mytestsofa.SOFABootWebSpringApplication 中,示例如下:

        @SpringBootApplication
        public class SOFABootWebSpringApplication{
             private static final Logger logger =LoggerFactory.getLogger(SOFABootWebSpringApplication.class);
        
             public static void main(String[] args){
                   //*************** 注意 ******************//
                  //本地同时启动 myserver-app 和 myclient-app 时,由于 tomcat 端口冲突问题,需要修改 myclient-app 的 端口号为 8084。
                  //将 myserver-app 和 myclient-app 发布到云上环境时,由于默认健康检查端口是 8080,所以需要注释掉该行代码。
                 System.setProperty("server.port","8084");
                 //由于本地启动没有注册中心,所以使用本地直连的方式访问本地启动的 myserver-app,发布到线上的时候需要注释掉该行代码。
                 System.setProperty("run.mode","TEST");
                 //********************************//
        
                 SpringApplication springApplication =newSpringApplication(SOFABootWebSpringApplication.class);
                 ApplicationContext applicationContext = springApplication.run(args);
        
                  if(logger.isInfoEnabled()){
                        printMsg("SofaRpc Application (myclient-app) started on 8084 port.");
                  }
        
                  ReferenceHolder referenceHolder = applicationContext.getBean(ReferenceHolder.class);
                  //调用 SOFAREST 服务。
                 final SampleRestFacade sampleRestFacade = referenceHolder.getSampleRestFacade();
        
                  new Thread(new Runnable(){
                     @Override
                     public void run(){
                          while(true){
                                  try{
                                           String response = sampleRestFacade.hello();
                                           printMsg("Response from myserver-app.rest: "+ response);
                                  }catch(Exception e){
                                         e.printStackTrace();
                                  }finally{
                                         try{
                                                 TimeUnit.SECONDS.sleep(3);
                                          }catch(InterruptedException e){
                                              //ignore
                                         }
                                    }
                              }
                         }
                  }).start();
              }
             private static void printMsg(String msg){
                  System.out.println(msg);
                   if(logger.isInfoEnabled()){
                         logger.info(msg);
                    }
             }
        }
  3. 配置包扫描。

    @SpringBootApplication(scanBasePackages ={"com.alipay.mytestsofa","com.alipay.samples.rpc"})
    public class SOFABootWebSpringApplication{
    ...
    }
  4. 配置本地运行的端口。

    1. myserver-app Web 模块 application.properties 文件中配置 rpc.tr.port=12201

      rpc.tr.port 是 TR 端口号,默认为 12200;TR = TaobaoRemoting 是 RPC 使用的底层通信框架。云端发布时不需要该项配置。

    2. 运行 Web 子模块中的 SOFABootWebSpringApplication

      运行后,框架会自动进行服务的发布。为了避免端口冲突,需要在该类中指定端口。

      重要

      myserver-app 发布至云上环境前,必须注释掉代码中对 8083 端口的配置。

    3. myclient-app Web 模块 application.properties 文件中配置 rpc.tr.port=12202

      rpc.tr.port 是 TR 端口号,默认为 12200。云端发布时不需要该项配置。

  5. 配置 application.properties

    1. 登录 SOFAStack 控制台

    2. 在左侧导航栏选择 中间件 > 中间件总览

      image

      从中获取以下信息:

      • instanceld(实例标识):应用实例在工作空间中的唯一标识。

        application.properties 中对应的 key 为 com.alipay.instanceid

      • AntVIP endpoint:区域的唯一标识,每个区域一个地址。应用通过 AntVIP 寻找所在区域环境的地址。不同环境的 AntVIP 地址值如下:

        • 杭州金区:cn-hangzhou-fin-middleware-acvip-prod.cloud.alipaycs.net

        • 上海非金:cn-shanghai-middleware-acvip-prod.cloud.alipaycs.net

        • 上海金区:cn-shanghai-fin-sofastack-middleware-acvip-prod.cloud.alipaycs.net

        • 杭州非金:cn-hangzhou-middleware-acvip-prod.cloud.alipaycs.net

        application.properties中对应的 key 为 com.antcloud.antvip.endpoint

      • Access Key ID:用于标识用户。单击 获取 AK 可前往 RAM 控制台获取。具体操作,请参见 创建AccessKey

        application.properties 中对应的 key 为 com.antcloud.mw.access

      • Access Key Secret:用于验证用户。单击 获取 SK 可前往 RAM 控制台获取。具体操作,请参见 创建AccessKey

        application.properties 中对应的 key 为 com.antcloud.mw.secret

    3. 配置运行模式和运行环境,示例如下:

      run.mode=NORMAL
      com.alipay.env=shared
    4. 将上述步骤获取的参数配置在 application.properties 文件中。

    说明

    更多信息,请参见 引入 SOFA 中间件

示例工程

下文以示例工程为例,对 SOFARPC 的实现原理进行说明。

示例概述

通过 IDEA 或 Eclipse 分别打开 rpc-demo 中的 myserver-appmyclient-app 工程。

示例工程关键信息

  • groupId: 工程组织的唯一标识,示例工程为 com.alipay.mytestsofa

  • artifactId:工程的构件标识符,示例工程为 myserver-appmyclient-app

  • version:版本号,默认为 1.0-SNAPSHOT

  • package:应用包名,默认等同于 groupId,工程示例为 com.alipay.mytestsofa

示例工程 Bean 配置

Bean 的配置分为服务发布和服务引用 2 个类型:

  • 服务发布的示例

    @SofaService(interfaceType =SampleRestFacade.class,bindings =@SofaServiceBinding(bindingType ="rest"))
  • 服务引用的示例

    @SofaReference(interfaceType =SampleRestFacade.class, binding =@SofaReferenceBinding(bindingType ="rest",directUrl ="127.0.0.1:8341"))
    private SampleRestFacade sampleRestFacade;
    说明

    示例中,为了便于对所有待引用实例进行统一管理,创建了 ReferenceHolder 类,进行引用管理。

示例工程的 REST 实现

SOFAREST 的实现基于 SOFARPC,SOFARPC 的实现原理说明如下:

  • 在 2 个工程的 endpoint 模块中相同位置,提供相同的服务接口和实现,并通过注解发现服务。2 个工程通过相同接口实现关联。一个客户端,一个服务端,如果是本地工程,在引用时,通过配置 directUrl,以直连方式发现服务;如果是服务器上部署测试,则通过 DSR(Direct Server Return) 底座发现服务。

  • 启动 myserver-app Web 模块的 SOFABootWebSpringApplication 可发布服务。

  • 启动 myclient-app Web 模块的 SOFABootWebSpringApplication 可引用服务。

示例工程服务验证

  1. 启动 myserver-app Web 模块的 SOFABootWebSpringApplication 发布服务。

  2. 启动 myclient-app Web 模块的 SOFABootWebSpringApplication 引用服务。

    引用成功后,myclient-app 控制台将输出:

    Response from myserver-app.rest:HelloSOFARest! times = xx

    本地浏览器访问 http://localhost:8341/sofarest/hello,将输出访问 URL 链接那一刻,客户端的调用次数。

    HelloSOFARest! times = xx

云端发布后,可以在客户端命令行中输入 curl http://{服务器 IP 地址}:8341/sofarest/hello 命令进行验证。

您也可以通过日志来查看服务引用结果:默认在 /logs/myclient-app/common-default.log 中查看服务引用结果。您可以在 Web 子模块路径 src/main/resources/config/application.properties 中修改日志路径。

应用打包和云端发布

  1. 打包本地应用。

    操作步骤,请参见 本地运行

  2. 发布应用。

    • 应用整体发布流程,请参见 技术栈使用指南

    • 应用的详细发布步骤,建议根据发布方式,参考下述文档:

服务管控

服务管控 页面查询并管控发布的 RPC 服务。更多详情,请参见 查看服务服务查询