eda设计的基本流程_开发规范「建议收藏」

eda设计的基本流程_开发规范「建议收藏」前言概述本文档主要介绍了服务开发者基于Aliware做项目开发时,从项目环境搭建,项目开发,项目上线及Aliware服务功能相关的使用说明,操作步骤及代码示例。应用范围服务开发者后端开发语言为JAVA。需要使用RPC(HSF)。需要EADS提供的应用管理(上下架管理,动态扩容、缩容)。需要应用服务监控服务(日志统一管理,运行环境监控,Jvm状态监控,请求链路分析)。…_edasxf

eda设计的基本流程_开发规范「建议收藏」

前言

概述

本文档主要介绍了服务开发者基于Aliware做项目开发时,从项目环境搭建,项目开发,项目上线及Aliware服务功能相关的使用说明,操作步骤及代码示例

应用范围

服务开发者

后端开发语言为JAVA。

需要使用RPC(HSF)。

需要EADS提供的应用管理(上下架管理,动态扩容、缩容)。

需要应用服务监控服务(日志统一管理,运行环境监控,Jvm状态监控,请求链路分析)。

 

更新历史

版本

/更新日期

更新内容

V1.0.0

20170719

第一次发布

V1.0.4

20170725

修改Maven 私服配置 settings.xml文件,代码去掉行号

 

 

目录

前言 1

概述 1

应用范围 1

更新历史 1

目录 2

1. 开发资源的申请 4

1.1. 阿里云开发子账号的申请 4

1.2. ECS的申请 4

1.3. Agent的申请 4

1.3.1. EDAS Agent 简介 4

1.3.2. 安装 Agent 5

2. 开发指南 9

2.1. 环境配置 9

2.1.1. Maven 私服配置 9

2.1.2. 安装轻量配置中心 10

2.2. 基于EDAS的HSF标准服务开发指南 11

2.2.1. 基于Spring开发 11

2.2.2. 基于SpringBoot开发 25

2.3. 带有验证能力的HSF服务开发指南 41

2.4. 申请调用其他HSF服务 41

2.5. 授权其他应用使用HSF服务 41

2.6. 开发规范 41

2.6.1. 工程结构规范 41

2.6.2. 命名规范 44

2.6.3. POJO 类定义规范 45

2.6.4. HSF使用规范 45

2.6.5. 异常处理规范 46

2.6.6. 日志规范 47

2.6.7. 返回值规范 48

3. 使用指南 51

3.1. 上架和部署说明 51

3.1.1. 登录 51

3.1.2. EDAS控制台入口 51

3.1.3. EDAS控制台 52

3.1.4. 创建应用 53

3.1.5. 设置应用类型和网络类型 55

3.1.6. 部署应用 55

3.1.7. 启动应用 57

3.1.8. 查看启动日志 58

3.2. 应用监控 59

3.2.1. 监控大盘 59

3.2.2. 基础监控 60

3.2.3. 服务监控 61

3.3. 全自动化测试方案 65

3.4. 全链路压测方案 65

 

 

 

开发资源的申请

 

阿里云开发子账号的申请

 

ECS的申请

 

Agent的申请

EDAS Agent 简介

EDAS Agent(以下简称 Agent)是 安装在 ECS 上,用于 EDAS 服务集群与部署在相应 ECS 上的应用程序之间进行通信的 Daemon 程序。在运行的过程中主要承担以下的角色:

应用管理:包括应用部署、启动、停止等。

状态回报:包括应用存活状态、健康检查状态、Ali-Tomcat 容器状态等。

信息获取:如获取 ECS 和容器的监控信息。

Agent 除了完成以上基于应用的管控功能,还负责 EDAS 控制台与用户应用程序之间通信。简单的说,一个应用发布的服务是否在某台 ECS 上正确及时的发布,这个简单的信息获取就需要 Agent 的参与和协调。

说明: 上述 Agent 所涉及的功能对用户都是透明的,作为用户,您只需要安装 Agent 即可。

 

安装 Agent

EDAS 只会选择安装了 Agent 的 ECS 进行应用的部署(包括第一次安装、扩容)。EDAS 计费系统中的节点的概念,也是指安装了 Agent 并且部署了应用的 ECS。所以在购买 ECS 之后,使用 EDAS 的第一个步骤就是安装 Agent。

注意事项

该脚本需要先以 root 身份登录用户的 ECS 终端手动执行。

目前 Agent 的安装及其运行环境仅支持 CentOS 6.5/6.8/7.0/7.2 64 位 与 Ali-Linux 5.7 64 位

该脚本可以重复执行,重复执行的结果是覆盖安装,所以 Agent 没有提供单独的升级脚本,即当需要升级 Agent 时,需要执行和安装时同样的脚本。

目前不同 Region 的 ECS 服务器所使用的安装脚本是不同的,在选择安装脚本之前一定要切换到 ECS 所对应的 Region 列表,然后再单击 安装 Agent 按钮。

安装步骤

登录 EDAS 控制台,在左侧导航栏中选择 资源管理 > 云服务器 ECS

在页面的左上角选择 ECS 所在区域,如“华东1”。

在 ECS 实例列表页面,选择相应的 ECS,单击右上角 安装 Agent 按钮。

在 EDAS Agent 安装对话框,选择相应的网络环境。

 

非 VPC 环境: 对应阿里云的 经典网络 模式,即相应的 ECS 如果处于经典网络时,选择 install.sh 脚本进行安装。

VPC 环境:是指相应的 ECS 处于 VPC 环境内部时,采用提示中的 install_vpc.sh 脚本进行安装。

在默认的列表中,用户可能无法找到对应的 ECS,造成这种情况一般存在以下原因:

实例没有在相应的区域中,可在左上角的区域列表(华东1华北1 等)中进行切换后确认。

后台的 ECS 列表没有同步完成,由于自动同步方式方式会存在一定时延,如切换相应的区域后仍未发现相应的 ECS ,可点击右上角的 同步 ECS 按钮触发手动同步。

如果手动同步依然失败,请检查阿里云上主账户的 Access Key ID/Access Key Secret 是否启用。

 

开始安装:可以选择单台机器进行单个安装,也可以选择多台机器进行批量安装,具体方法:

安装单个 Agent

在对话框中,拷贝 非 VPC 环境 区域中的命令。

以 root 身份登录该 ECS。

在 ECS 终端中,粘贴拷贝的命令并执行。

稍等片刻,脚本执行成功后会出来如下信息:

 

[root@iHostname]# wget -q -O /root/install.sh http://edas-hz.oss-cn-hangzhou-internal.aliyuncs.com/install.sh && sh /root/install.sh -ak {your-access-key} -sk {your-secret-key}

….

….

….

Edas Install Success!

说明:在安装时,如果有特定安装需求,比如 JDK 或 EDAS 的版本,可以输入不同参数进行设置。

执行 sh /root/install.sh -h,可出现如下的信息:

[root@devhome ~]# sh install.sh h

ENV: cnhangzhou

Usage: install.sh ak <ak> sk <sk>

[-L|–list] [-java <7(default)|8>] [-version <2.13.0(default)>] [-force]

其中每个参数的具体含义为:

-ak : 用户 EDAS Access Key,在用户开通 EDAS 服务时创建,主要用于 EDAS 应用上的 HSF 服务鉴权、配置管理等功能。每次执行 EDAS Agent 安装升级时必选。

说明:此 Access Key 与阿里云服务的 Access Key 无关。

-sk : 用户 EDAS Access Key 对应的 Seceret Key,此参数每次执行 EDAS Agent 安装升级时必选。

-L 或 —list : 列举当前 EDAS 环境可用的 EDAS Agent 版本信息,执行后输出信息如下:

[root@devhome ~]# sh install.sh L

ENV: cnhangzhou

2.10.2, 2.11.2, 2.13.0

-java : 指定运行时安装的 JDK 版本(选择 7 为 JDK7,选择 8 为 JDK8,目前 EDAS 上只支持这两种 JDK 版本)。此 JDK 将作用于 EDAS 上应用的 JVM 执行环境,安装完成后,JAVA_HOME 路径为:/usr/java/default。

注意:在安装 JDK 的过程中,如果发现之前安装有 JDK,且版本与指定版本不一致的情况,会将之前安装的版本卸载(绿色版除外)。

-version : 指定安装 EDAS 的版本,可结合 -L|—list 参数选择安装版本。

-force : 由于安装 EDAS Agent 时,需要安装很多依赖的组件,当第二次进行 EDAS Agent 升级时,如果没有指定 -force 参数,则不会将依赖的组件进行重新安装;相反,如果指定了此参数,将会重新安装所有组件。

在机器上确认 Agent 是否运行正常。

[root@iHostname]# pgrep f ‘AgentDaemon’ && egrep ‘Register ecu’ /home/admin/edasagent/logs/agent.log

14:25:36 [main] INFO  com.alibaba.edas.agent.AgentDaemon  Register ecu into edas successfully

在 EDAS 控制台中确认相应的 ECS 是否已经安装了正确的版本,如下图:

 

批量安装 Agent

单击 安装 Agent 按钮,在弹出的对话框下方有相应网络环境下批量安装 Agent 的脚本说明,如图:

 

批量安装与单个安装基本思路一样,不同的是需要在执行脚本的机器上填充待安装机器 IP 列表,输入相应的 root 密码(所有机器密码都应是一样的),且保证此机器与其它待安装机器的网络可连接。具体步骤可参见上图。

 

开发指南

环境配置

Maven 私服配置

注意: Maven 版本要求 3.x 及以上请在你的 Maven 配置文件 Setting 中,加入中间件私服地址。

 

<mirrors>

    <mirror> 

        <id>alimaven</id> 

        <name>aliyun maven</name> 

        <url>http://maven.aliyun.com/nexus/content/groups/public/</url> 

        <mirrorOf>central</mirrorOf> 

    </mirror>

</mirrors>

<profiles>

    <profile>

        <id>edas.oss.repo</id>

<activation>

             <activeByDefault>true</activeByDefault>

         </activation>

 

        <repositories>

            <repository>

                <id>edas-oss-central</id>

                <name>taobao mirror central</name>

                <url>http://edas-public.oss-cn-hangzhou.aliyuncs.com/repository</url>

                <snapshots>

                    <enabled>true</enabled>

                </snapshots>

                <releases>

                    <enabled>true</enabled>

                </releases>

            </repository>

        </repositories>

        <pluginRepositories>

            <pluginRepository>

                <id>edas-oss-plugin-central</id>

                <url>http://edas-public.oss-cn-hangzhou.aliyuncs.com/repository</url>

                <snapshots>

                    <enabled>true</enabled>

                </snapshots>

                <releases>

                    <enabled>true</enabled>

                </releases>

            </pluginRepository>

         </pluginRepositories>

    </profile>

</profiles>

 

<activeProfiles>

    <activeProfile>edas.oss.repo</activeProfile>

</activeProfiles>

 

注意:如果遇到EDAS相关Jar包在maven上更新不下来时,<mirrors>标签中只保留 alimaven的镜像,注释其他镜像。

安装轻量配置中心

轻量配置中心给开发者提供在开发、调试、测试的过程中的服务发现、注册和查询功能。此模块不属于 EDAS 正式环境中的服务,使用时请下载安装包进行安装。

在一个公司内部,通常只需要在一台机器上安装轻量配置中心服务,并在其他开发机器上绑定特定的 Host 即可。具体安装和使用的步骤请参见下文。

安装轻量配置中心

首先,请确认环境是否达到要求:

正确配置环境变量 JAVA_HOME,指向一个 1.8版本的 JDK。

确认 8080 和 9600 端口未被使用。由于启动 EDAS 配置中心将会占用此台机器的 8080 和 9600 端口,因此推荐您找一台专门的机器启动 EDAS 配置中心,比如某台测试机器。如果您是在一台机器上进行测试,请将 Web 项目的端口修改为其它未被占用的端口。

然后,启动 EDAS 配置中心:

下载 EDAS 配置中心安装包并解压。

进入 edas-config-center 目录启动配置中心:

Windows 系列操作系统请双击 startup.bat。

Unix 系列操作系统请在当前目录下执行 sh startup.sh 命令。

轻量配置中心的使用

对于需要使用轻量配置中心的开发机器,请在本地 DNS(hosts 文件)中,将 jmenv.tbsite.net 域名指向启动了 EDAS 配置中心的机器 IP。

hosts 文件的路径如下:

Windows 系列操作系统:C:\Windows\System32\drivers\etc\hosts

Unix 系列操作系统:/etc/hosts

示例:

如果您在 IP 为 192.168.1.100 的机器上面启动了 EDAS 配置中心,则所有开发者只需要在机器的 hosts 文件里加入如下一行即可。

192.168.1.100 jmenv.tbsite.net

绑定 Host 解析后,HSF 服务将基于此注册中心进行服务注册与发现。

 

基于EDAS的HSF标准服务开发指南

基于Spring开发

开发工具准备

Ali-Tomcat 安装

点击链接地址,下载 Ali-Tomcat,保存后解压至相应的目录(如:d:\work\tomcat)。

点击链接地址,下载 Pandora 容器,保存后将内容解压至上述保存的 Ali-Tomcat 的 deploy 目录(d:\work\tomcat\deploy)下。最后出来的目录结构如下

注意:请使用 JDK 1.7及以上版本。

配置 Eclipse 开发环境

配置 Eclipse 需要先下载 Tomcat4E 插件,然后选择Pandora 容器路径,配置之后开发者可以直接在 Eclipse 中发布、调试本地代码。具体步骤如下:

点击链接下载 Tomcat4E 插件并解压至本地,如:d:\work\tomcat4e\。压缩包内容如下:

 

打开 Eclipse,点击工具栏菜单> Help 按钮,选择 Install New Software,弹出如下对话框。依次单击 Add > Local,选中解压好的 Tomcat4E 插件目录(d:\work\tomcat4e\)>,单击 OK

 

单击 Select All > Next 按钮即完成插件安装。

 

重启 Eclipse。

要使 Tomcat4E 生效,需要针对相应的 Eclipse 工程进行单独设置。右键单击相应的 Eclipse 工程,在弹出的菜单中选中 Run As >单击 Run Configurations

 

选择左侧导航选项中的 AliTomcat Webapp,单击上方的 新增启动配置

在弹出的界面中,选择 AliTomcat 选项卡,在 Pandora (taobao-hsf.sar location) 区域,选择 Use local taobao-hsf.sar,并单击旁边的 Browse 以选择本地的 Pandora 路径,如:d:\work\tomcat\deploy\taobao-hsf.sar。

 

单击 Apply 或 Run,完成设置。一个工程只需配置一次,下次可直接启动。

 

配置 IntelliJ IDEA开发环境

IDEA 的配置不需要依赖额外的插件,而是通过JVM启动参数 -Dpandora.location 来不过目前 IDEA 仅仅支持商业版,社区版本暂不支持此种方式。具体步骤如下:

从菜单中或者工具栏中点击 Run,选择 Edit Configuration

 

单击界面的加号(+),选择 Tomcat Server,单击 Local,以增加一个本地 Tomcat 的启动配置。

 

配置 AliTomcat:在右侧页面选择 Server 选项卡,在 Application Server 区域,点击 Configure。 然后在弹出的页面中选择AliTomcat路径,如:d:\work\tomcat\

 

配置好 AliTomcat 后,在 Application Server 区域的下拉菜单中,选择刚刚配置好的 AliTomcat 实例。

 

在 VM Options 区域,增加 JVM 启动参数指向 Pandora 的路径,如:-Dpandora.location=d:\work\tomcat\deploy\taobao-hsf.sar

单击 Apply 或 OK 完成配置。

工程构建

创建MavenWeb 服务

创建工程目录如下图:

 

其中 api 工程提供接口定义,consumer工程是消费者应用,provider 工程是服务提供者应用。

添加Maven依赖

在项目consumer和provider工程的pom.xml中添加如下依赖

<dependencies>

<!– servlet-api dependency 建议3.0以上版本 –>
   <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>3.0.1</version>
      <scope>provided</scope>
   </dependency>

   <!– spring dependency, 2.5.6(及其以上版本)–>
   <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>4.2.3.RELEASE</version>
   </dependency>

 

<!– edas dependency 必须依赖–>
    <dependency>
      <groupId>com.alibaba.edas</groupId>
      <artifactId>edas-sdk</artifactId>
      <version>1.5.4</version>
   </dependency>
</dependencies>
<build>
   <finalName>detail</finalName>
   <plugins>
      <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-compiler-plugin</artifactId>
         <version>3.1</version>
         <configuration>
            <source>1.7</source>
            <target>1.7</target>
         </configuration>
      </plugin>
   </plugins>
</build>

服务发布

定义接口

HSF 的服务基于接口实现,当接口定义好之后,生产者将实现该接口以提供具体的实现来提供服务,消费者也是基于此接口作为服务去订阅。

在api工程中定义一个服务接口ItemService,此接口将提供两个方法getItemById 与 getItemByName。

public interface ItemService {

   Item getItemById( long id );
   
   Item getItemByName( String name );
   
}

生产者实现接口类

provider工程中创建实现类ItemServiceImpl。

public class ItemServiceImpl implements ItemService {

   @Override
   public Item getItemById( long id ) {

      Item car = new Item();
      car.setItemId( 1l );
      car.setItemName( “Test Item GetItemById” );
      return car;
   }
   @Override
   public Item getItemByName( String name ) {

      Item car = new Item();
      car.setItemId( 1l );
      car.setItemName( ” Test Item GetItemByName” );
      return car;
   }
}

生产者配置

provider工程中 web.xml 中配置 spring 的监听器: 

<context-param>
   <param-name>contextConfigLocation</param-name>
   <param-value>classpath:hsf-provider-beans.xml</param-value>
</context-param>

<listener>
   <listener-class>org.springframework.web.context.ContextLoaderListener
   </listener-class>
</listener>

 

在 resources 目录下面添加 spring 配置文件:config/hsf-provider-beans.xml 

 

 

<?xml version=”1.0″ encoding=”UTF-8″?>
<beans xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
       xmlns:hsf=”http://www.taobao.com/hsf”
       xmlns=”http://www.springframework.org/schema/beans”
       xsi:schemaLocation=”http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://www.taobao.com/hsf
       http://www.taobao.com/hsf/hsf.xsd” default-autowire=”byName”>
    <bean id=”itemService” class=”cn.com.flaginfo.edas.demo.itemcenter.ItemServiceImpl” />
    <!– 提供一个服务示例 –>
    <hsf:provider id=”itemServiceProvider” interface=”cn.com.flaginfo.edas.demo.itemcenter.ItemService”
        ref=”itemService” version=”1.0.0″ group=”test”>
    </hsf:provider>
</beans>

生产者配置属性清单

关于 HSF 生产者的属性配置,除了上述内容提到的之外,还有如下的内容可供选择:

属性

描述

interface

interface 必须配置 [String],为服务对外提供的接口

version

version 为可选配置 [String],含义为服务的版本,默认为 1.0.0

group

serviceGroup 为可选配置 [String],含义为服务所属的组别,以便按组别来管理服务的配置,默认为 HSF

clientTimeout

该配置对接口中的所有方法生效,但是如果客户端通过 MethodSpecial 属性对某方法配置了超时时间,则该方法的超时时间以客户端配置为准,其他方法不受影响,还是以服务端配置为准

serializeType

serializeType 为可选配置 [String(hessian|java)],含义为序列化类型,默认为 hessian

corePoolSize

单独针对这个服务设置核心线程池,是从公用线程池这个大蛋糕里切一块下来

maxPoolSize

单独针对这个服务设置线程池,是从公用线程池这个大蛋糕里切一块下来

enableTXC

开启分布式事务 TXC

ref

ref 必须配置 [ref],为需要发布为 HSF 服务的 Spring Bean ID

methodSpecials

methodSpecials 为可选配置,用于为方法单独配置超时(单位 ms),这样接口中的方法可以采用不同的超时时间,该配置优先级高于上面的 clientTimeout 的超时配置,低于客户端的 methodSpecials 配置

 

服务订阅

消费者配置

consumer工程中 web.xml 中配置 spring 的监听器: 

<context-param>
   <param-name>contextConfigLocation</param-name>
   <param-value>classpath:hsf-consumer-beans.xml</param-value>
</context-param>

<listener>
   <listener-class>org.springframework.web.context.ContextLoaderListener
   </listener-class>
</listener>

 

在 resources 目录下面添加 spring 配置文件:config/hsf-consumer-beans.xml 

<?xml version=”1.0″ encoding=”UTF-8″?>
<beans xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
       xmlns:hsf=”http://www.taobao.com/hsf”
       xmlns=”http://www.springframework.org/schema/beans”
       xsi:schemaLocation=”http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://www.taobao.com/hsf
       http://www.taobao.com/hsf/hsf.xsd” default-autowire=”byName”>
    <!– 消费一个服务示例 –>
    <hsf:consumer id=”item” interface=”cn.com.flaginfo.edas.demo.itemcenter.ItemService”
    version=”1.0.0″ group=”test”>
    </hsf:consumer>
</beans>

在consumer工程中创建实现类测试Servlet类

public class IndexServlet extends HttpServlet {

   @Override
   public void doGet( HttpServletRequest req, HttpServletResponse resp ) throws ServletException, IOException {

      ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(
         req.getServletContext());
      ItemService itemService = (ItemService) ctx.getBean(“item”);
      resp.getWriter().println(itemService.getItemById(10));
   }
   
   @Override
   protected void doPost( HttpServletRequest req, HttpServletResponse resp ) throws ServletException, IOException {

   }

}

在web.xml中添加servlet配置

<servlet>
   <servlet-name>IndexServlet</servlet-name>
   <servlet-class>cn.com.flaginfo.edas.demo.detail.IndexServlet</servlet-class>
</servlet>
<servlet-mapping>
   <servlet-name>IndexServlet</servlet-name>
   <url-pattern>/index.htm</url-pattern>
</servlet-mapping>

消费者配置属性清单

除了示例代码中体现的属性(interface,group,version)之外,还有下表的属性配置以供选择:

属性

描述

interface

interface 必须配置 [String],为需要调用的服务的接口

version

version 为可选配置 [String],含义为需要调用的服务的版本,默认为1.0.0

group

group 为可选配置 [String],含义为需要调用的服务所在的组,以便按组别来管理服务的配置,默认为 HSF,建议配置

methodSpecials

methodSpecials 为可选配置,含义为为方法单独配置超时(单位 ms),这样接口中的方法可以采用不同的超时时间,该配置优先级高于服务端的超时配置

target

主要用于单元测试环境和 hsf.runmode=0 的开发环境中,在运行环境下,此属性将无效,而是采用配置中心推送回来的目标服务地址信息

connectionNum

connectionNum 为可选配置,含义为支持设置连接到 server 连接数,默认为1,在小数据传输,要求低延迟的情况下设置多一些,会提升 TPS

clientTimeout

客户端统一设置接口中所有方法的超时时间(单位 ms),超时设置优先级由高到低是:客户端 MethodSpecial,客户端接口级别,服务端 MethodSpecial,服务端接口级别

asyncallMethods

asyncallMethods 为可选配置 [List],含义为调用此服务时需要采用异步调用的方法名列表以及异步调用的方式。默认为空集合,即所有方法都采用同步调用

maxWaitTimeForCsAddress

配置该参数,目的是当服务进行订阅时,会在该参数指定时间内,阻塞线程等待地址推送,避免调用该服务时因为地址为空而出现地址找不到的情况。若超过该参数指定时间,地址还是没有推送,线程将不再等待,继续初始化后续内容。

 

打包运行

完成代码和配置的开发任务之后,在 Eclipse 和 IDEA 中,可直接以 Ali-Tomcat 运行该服务。

在 Eclipse 和 IDEA 中可以用maven插件打包,maven插件中在项目root目录执行install。

或者用Maven命令打包项目

使用命令提示符( Win 环境)或 SHELL 终端(Linux 环境)进入到示例工程目录。

打包 api:cd api && mvn clean install && cd ../

打包 provider 工程:cd provider && mvn clean package && cd ../

打包 consumer 工程:cd consumer && mvn clean package && cd ../

 

基于SpringBoot开发

工程构建

创建MavenWeb 服务

创建工程目录如下图:

 

父目录pom.xml文件配置

<parent>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-parent</artifactId>
   <version>1.4.0.RELEASE</version>
</parent>

<properties>
   <spring-cloud-starter-pandora.version>1.0</spring-cloud-starter-pandora.version>
   <spring-cloud-starter-hsf.version>1.0</spring-cloud-starter-hsf.version>
   <spring-cloud-starter-sentinel.version>1.0</spring-cloud-starter-sentinel.version>
</properties>

<dependencyManagement>
   <dependencies>
      <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-dependencies</artifactId>
         <version>Camden.SR3</version>
         <type>pom</type>
         <scope>import</scope>
      </dependency>

      <!– 用户需要依赖的Api –>
      <dependency>
         <groupId>cn.com.flaginfo.edas</groupId>
         <artifactId>pandora-hsf-boot-demo-api</artifactId>
         <version>0.0.1-SNAPSHOT</version>
      </dependency>
      
      <!– Alibaba Aliware –>
      <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-pandora</artifactId>
         <version>${spring-cloud-starter-pandora.version}</version>
      </dependency>
      <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-hsf</artifactId>
         <version>${spring-cloud-starter-hsf.version}</version>
      </dependency>
      <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-sentinel</artifactId>
         <version>${spring-cloud-starter-sentinel.version}</version>
      </dependency>

      <dependency>
         <groupId>javax.servlet</groupId>
         <artifactId>javax.servlet-api</artifactId>
         <version>3.1.0</version>
      </dependency>

   </dependencies>
</dependencyManagement>

在项目consumer和provider工程的pom.xml中添加如下依赖

<dependencies>
   <!– 用户需要依赖的Api –>
   <dependency>
      <groupId>cn.com.flaginfo.edas</groupId>
      <artifactId>pandora-hsf-boot-demo-api</artifactId>
   </dependency>

   <!– spring dependency –>
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
   </dependency>

   <!– Alibaba Aliware 依赖 –>
   <!– pandora-boot启动依赖 –>
   <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-pandora</artifactId>
   </dependency>
   <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-hsf</artifactId>
   </dependency>
   <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-sentinel</artifactId>
   </dependency>
   
   <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
   </dependency>

   <dependency>
      <groupId>com.alibaba.edas.configcenter</groupId>
      <artifactId>configcenter-client</artifactId>
      <version>1.0.2</version>
   </dependency>

</dependencies>

<build>
   <plugins>
      <!– 该插件用于生成fat jar,并且主动排除taobao-hsf.sar这个jar包,该jar包在生产环境部署时会通过-D参数指定,所以打包时无需打包,避免资源浪费 –>
      <plugin>
         <groupId>com.taobao.pandora</groupId>
         <artifactId>pandora-boot-maven-plugin</artifactId>
         <version>2.1.6.3</version>
         <executions>
            <execution>
               <phase>package</phase>
               <goals>
                  <goal>repackage</goal>
               </goals>
            </execution>
         </executions>
      </plugin>
   </plugins>
</build>

application.properties配置

#服务名称
spring.application.name=pandora-hsf-boot-demo-consumer
#端口号
server.port=8082

启动代码

在项目consumer和provider工程的springBoot启动类中中添加如下代码

@SpringBootApplication
//设置HSF的配置文件及限流降级配置
@ImportResource(locations = {
“classpath:hsf-beans.xml”,“classpath*:sentinel-tracer.xml”})
public class HSFBootDemoConsumerApplication {

    public static void main(String[] args) {

        // 启动Pandora Boot 用于加载Pandora容器
        PandoraBootstrap.run(args);
        SpringApplication.run(HSFBootDemoConsumerApplication.class, args);
        // 标记服务启动完成,并设置线程wait。 通常在main函数最后一行调用。
        PandoraBootstrap.markStartupAndWait();

    }
}

服务发布

定义接口

HSF 的服务基于接口实现,当接口定义好之后,生产者将实现该接口以提供具体的实现来提供服务,消费者也是基于此接口作为服务去订阅。

在api工程中定义一个服务接口ItemService,此接口将提供两个方法getItemById 与 getItemByName。

public interface ItemService {

   Item getItemById( long id );
   
   Item getItemByName( String name );
   
}

生产者实现接口类

provider工程中创建实现类ItemServiceImpl。

public class ItemServiceImpl implements ItemService {

   @Override
   public Item getItemById( long id ) {

      Item car = new Item();
      car.setItemId( 1l );
      car.setItemName( “Test Item GetItemById” );
      return car;
   }
   @Override
   public Item getItemByName( String name ) {

      Item car = new Item();
      car.setItemId( 1l );
      car.setItemName( ” Test Item GetItemByName” );
      return car;
   }
}

生产者配置

在 resources 目录下面添加 spring 配置文件:config/hsf-provider-beans.xml 

 

 

<?xml version=”1.0″ encoding=”UTF-8″?>
<beans xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
       xmlns:hsf=”http://www.taobao.com/hsf”
       xmlns=”http://www.springframework.org/schema/beans”
       xsi:schemaLocation=”http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://www.taobao.com/hsf
       http://www.taobao.com/hsf/hsf.xsd” default-autowire=”byName”>
    <bean id=”itemService” class=”cn.com.flaginfo.edas.demo.itemcenter.ItemServiceImpl” />
    <!– 提供一个服务示例 –>
    <hsf:provider id=”itemServiceProvider” interface=”cn.com.flaginfo.edas.demo.itemcenter.ItemService”
        ref=”itemService” version=”1.0.0″ group=”test”>
    </hsf:provider>
</beans>

生产者配置属性清单

关于 HSF 生产者的属性配置,除了上述内容提到的之外,还有如下的内容可供选择:

属性

描述

interface

interface 必须配置 [String],为服务对外提供的接口

version

version 为可选配置 [String],含义为服务的版本,默认为 1.0.0

group

serviceGroup 为可选配置 [String],含义为服务所属的组别,以便按组别来管理服务的配置,默认为 HSF

clientTimeout

该配置对接口中的所有方法生效,但是如果客户端通过 MethodSpecial 属性对某方法配置了超时时间,则该方法的超时时间以客户端配置为准,其他方法不受影响,还是以服务端配置为准

serializeType

serializeType 为可选配置 [String(hessian|java)],含义为序列化类型,默认为 hessian

corePoolSize

单独针对这个服务设置核心线程池,是从公用线程池这个大蛋糕里切一块下来

maxPoolSize

单独针对这个服务设置线程池,是从公用线程池这个大蛋糕里切一块下来

enableTXC

开启分布式事务 TXC

ref

ref 必须配置 [ref],为需要发布为 HSF 服务的 Spring Bean ID

methodSpecials

methodSpecials 为可选配置,用于为方法单独配置超时(单位 ms),这样接口中的方法可以采用不同的超时时间,该配置优先级高于上面的 clientTimeout 的超时配置,低于客户端的 methodSpecials 配置

 

服务订阅

消费者配置

在 resources 目录下面添加 spring 配置文件:config/hsf-consumer-beans.xml 

<?xml version=”1.0″ encoding=”UTF-8″?>
<beans xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
       xmlns:hsf=”http://www.taobao.com/hsf”
       xmlns=”http://www.springframework.org/schema/beans”
       xsi:schemaLocation=”http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://www.taobao.com/hsf
       http://www.taobao.com/hsf/hsf.xsd” default-autowire=”byName”>
    <!– 消费一个服务示例 –>
    <hsf:consumer id=”item” interface=”cn.com.flaginfo.edas.demo.itemcenter.ItemService”
    version=”1.0.0″ group=”test”>
    </hsf:consumer>
</beans>

在consumer工程中创建实现类测试DemoController类

@Controller
@RequestMapping(“demo”)
public class DemoController {

   @Autowired
   private ItemService itemService;

   @ResponseBody
   @RequestMapping(method = RequestMethod.GET)
   public String testItem() {

      Item item = itemService.getItemById(10);
      System.out.println(“getItemById=” + item);
      return item.toString();
   }

}

消费者配置属性清单

除了示例代码中体现的属性(interface,group,version)之外,还有下表的属性配置以供选择:

属性

描述

interface

interface 必须配置 [String],为需要调用的服务的接口

version

version 为可选配置 [String],含义为需要调用的服务的版本,默认为1.0.0

group

group 为可选配置 [String],含义为需要调用的服务所在的组,以便按组别来管理服务的配置,默认为 HSF,建议配置

methodSpecials

methodSpecials 为可选配置,含义为为方法单独配置超时(单位 ms),这样接口中的方法可以采用不同的超时时间,该配置优先级高于服务端的超时配置

target

主要用于单元测试环境和 hsf.runmode=0 的开发环境中,在运行环境下,此属性将无效,而是采用配置中心推送回来的目标服务地址信息

connectionNum

connectionNum 为可选配置,含义为支持设置连接到 server 连接数,默认为1,在小数据传输,要求低延迟的情况下设置多一些,会提升 TPS

clientTimeout

客户端统一设置接口中所有方法的超时时间(单位 ms),超时设置优先级由高到低是:客户端 MethodSpecial,客户端接口级别,服务端 MethodSpecial,服务端接口级别

asyncallMethods

asyncallMethods 为可选配置 [List],含义为调用此服务时需要采用异步调用的方法名列表以及异步调用的方式。默认为空集合,即所有方法都采用同步调用

maxWaitTimeForCsAddress

配置该参数,目的是当服务进行订阅时,会在该参数指定时间内,阻塞线程等待地址推送,避免调用该服务时因为地址为空而出现地址找不到的情况。若超过该参数指定时间,地址还是没有推送,线程将不再等待,继续初始化后续内容。

 

配置中心

添加依赖

<dependency>
   <groupId>com.alibaba.edas.configcenter</groupId>
   <artifactId>configcenter-client</artifactId>
   <version>1.0.2</version>
</dependency>

 

示例代码

public class ConfigCenter {

    // 属性/开关
    private static String config = “”;
    //初始化的时候,给配置添加监听
    private static void initConfig() {

        ConfigService.addListener(“hsfDemoConsumer”, “hsfConfigTest”,
            new ConfigChangeListener() {

                public void receiveConfigInfo(String configInfo) {

                    try {

                        //当配置更新后,马上获取新的配置
                        config = configInfo;
                        System.out.println(configInfo);
                    } catch (Exception e) {

                        e.printStackTrace();
                    }
                }
            });
    }

    // 通过get接口把配置值暴露出去使用
    public static String getConfig() {

        return config;
    }
}

 

单元测试

添加依赖

<dependency>
   <groupId>com.alibaba.hsf</groupId>
   <artifactId>LightApi</artifactId>
   <version>1.0.0</version>
</dependency>

<dependency>
   <groupId>org.mockito</groupId>
   <artifactId>mockito-all</artifactId>
</dependency>

<dependency>
   <groupId>com.taobao.pandora</groupId>
   <artifactId>pandora-boot-test</artifactId>
   <version>2.1.6.3</version>
</dependency>

示例代码

@RunWith(PandoraBootRunner.class)
@DelegateTo(SpringJUnit4ClassRunner.class)
// 加载测试需要的类,一定要加入Spring Boot的启动类,其次需要加入本类
@SpringBootTest(classes = { HSFBootDemoProviderApplication.class, VersionInfoTest.class })
@Component
public class VersionInfoTest {

    //当这里使用 @HSFConsumer 时,一定要在 @SpringBootTest 类加载中,加载本类,通过本类来注入对象,否则当做泛化时,会报类转换异常
    @HSFConsumer(generic = true, serviceGroup = “test” ,serviceVersion = “1.0.0”)
    private VersionInfoService versionInfoService;

    @Autowired
    ApplicationService applicationService;

    @Test
    public void testInvoke() {

        System.out.println(applicationService.getApplication());
        System.out.println(“#####:”+ versionInfoService.getVersionInfo());
        TestCase.assertEquals(“V1.0.0”, versionInfoService.getVersionInfo());
    }
    @Test
    public void testGenericInvoke() {

        GenericService service = (GenericService) versionInfoService;
        Object result = service.$invoke(“getVersionInfo”, new String[] {}, new Object[] {});
        System.out.println(“####:”+result);
        TestCase.assertEquals(“V1.0.0”, result);
    }
    @Test
    public void testMock() {

        VersionInfoService mock = Mockito.mock(VersionInfoService.class, AdditionalAnswers.delegatesTo(versionInfoService));
        Mockito.when(mock.getVersionInfo()).thenReturn(“V1.9.beta”);
        TestCase.assertEquals(“V1.9.beta”, mock.getVersionInfo());
    }
}

Actuator监控

添加依赖

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

在application.properties中添加配置

#health接口信息详情配置
endpoints.health.sensitive=false
#端口号必须为7002,否则会报错
management.port=7002

使用方法

http请求Get方式直接调用接口获得返回值信息

例如:http://127.0.0.1:7002/health

注意:因为PandoraBoot重新定义了 actuator启动端口,固定为7002,所以开发环境多个工程配置会报端口占用错误。

部署及运行

本地部署

在 IDE 中,通过 main 方法直接启动。

本地打包 FatJar ,通过 JAVA 命令启动。

排除 taobao-hsf.sar 依赖启动方式(加入-D 指定 SAR 位置)

#java -jar -Dpandora.location=/Users/Jason/.m2/repository/com/taobao/pandora/taobao-hsf.sar/3.2/taobao-hsf.sar-3.2.jar pandora-hsf-boot-demo-provider-0.0.1-SNAPSHOT.jar

说明:-Dpandora.location 指定的位置(可以是一个解压的目录或者 JAR 包)

例如: java jar  Dpandora.location=/path/to/your/taobaohsf.sar your_app.jar

注意: -Dpandora.location 指定的路径必须是全路径

不排除 taobao-hsf.sar 依赖启动方式(通过插件设置)通过 pandora-boot-maven-plugin 插件,把 excludeSar 设置为 false ,默认是 true ,打包时就会自动包含该 SAR 包。

<plugin>

  <groupId>com.taobao.pandora</groupId>

  <artifactId>pandora-boot-maven-plugin</artifactId>

  <version>2.1.6.3</version>

  <configuration>

    <excludeSar>false</excludeSar>

 </configuration>

  <executions>

      <execution>

          <phase>package</phase>

          <goals>

              <goal>repackage</goal>

          </goals>

      </execution>

  </executions>

</plugin>

直接启动

java jar pandorahsfbootdemoprovider0.0.1SNAPSHOT.jar

EDAS中部署

在应用管理中,创建的应用需要选择支持 FatJar 功能的容器。选择部署应用,上传 FatJar 应用即可部署。那么以后默认该应用只能上传 FatJar 了,不再支持 WAR 。

 

 

开发规范

工程结构规范

基础工程结构

该结构适用于只提供RPC生产者接口的服务,例如:评论服务,签到服务等。

项目示例

项目名称为:通用评论

项目名称缩写为:common-comment

目录结构示例:

 

核心目录结构说明:

目录名称

名录描述

common-comment

父目录

common-comment-api

RPC接口定义目录

common-commentcommon

通用类目录

common-comment-service

RPC接口实现目录,即生产者

 

Package结构示例:

 

核心Package结构说明:

Module名称

Package名称

Package描述

common-comment-api

api.domain

service相关的实体类(BO类)所在包

api.service

RPC生产者接口所在包

common-comment-service

dao

数据库ORM映射接口所在包

dao.impl

数据库ORM实现类所在包

domain

数据库表对应实体类(DO类)所在包

service.impl

RPC生产者接口实现类所在包

common-commentcommon

code

返回值代码枚举类所在包

domain

通用返回值结果封装类所在包

注意:为了方便排版Package名称列中省略前置package,实际项目中必须含有前置cn.com.flaginfo.项目名称(项目名称为小写无连接符号)。

复杂项目结构

该结构适用于有很多业务功能及有web功能的项目,例如:党建项目。

项目示例

项目名称为:金华消防

项目名称缩写为:jhxf

目录结构示例:

 

目录结构说明:

【强制】XXX-admin-web:为PC端前端代码及视图控制层代码(controller)。

【强制】XXX-app-web: 为手机端端前端代码及视图控制层代码(controller)。

【推荐】XXX-service:业务处理模块依据业务及功能调用情况,可以拆分为多个service模块。

例如:某个资源消耗(CPU,内存,线程,硬盘IO等)比较高的功能或爆发高的功能,建议单独拆分一个service提供RPC服务,在服务器资源紧张的时候,既不会影响其他功能的正常使用,也方便针对性的对服务器动态扩容和缩容。

命名规范

项目命名

【强制】服务类项目命名,依据项目实际功能小写英文单词全拼,单词之间用英文减号“-”分隔。

例如common-comment

【强制】业务类项目命名,依据项目所在地区-项目名称小写中文拼音,拼音太长可用缩写及英文减号“-”分隔。

例如jhxf

项目模块命名

【强制】项目模块命名规则为项目名称缩写-模块名称

例如jhxf-service, common-comment-api

RPC接口及实现类命名

【强制】服务类和业务类的RPC接口都定义在api.service,命名为XXXXService。

【强制】接口实现类在各自业务service模块的service.impl命名为XXXXServiceImpl。

GroupId命名

DataId命名

POJO 类定义规范

【强制】所有的 POJO (DO,BO,VO)类属性必须使用包装数据类型

【强制】RPC 方法的返回值和参数必须使用包装数据类型

【强制】POJO 类中布尔类型的变量,都不要加 is,否则部分框架解析会引起序列化错误。

例如:定义为基本数据类型 Boolean isDeleted;的属性,它的方法也是 isDeleted(),RPC框架在反向解析的时候,“以为”对应的属性名称是 deleted,导致属性获取不到,进而抛出异 常。

HSF使用规范

【推荐】HSF配置方式目前推荐xml的方式进行配置。xml方式方便统一的进行配置管理,更直观的了解已配置接口功能,配置属性也比注解方式更灵活更丰富。

生产者(RPC服务提供者)

【强制】<hsf:provider>必须配置group参数和version参数。

例如

<hsf:provider id=”versionInfoService”
interface=”cn.com.flaginfo.edas.demo.service.VersionInfoService” group=”test” version=”1.0.0″ ref=”versionInfoServiceImpl” />

消费者(RPC服务调用者)

【强制】<hsf:consumer>必须配置group参数和version参数。

例如

<hsf:consumer id=”applicationService” version=”1.0.0″ group=”test”
interface=”cn.com.flaginfo.edas.demo.service.ApplicationService”/>

【推荐】RPC消费者使用异步调用时,需要结合业务场景做充足的测试后再使用。因为该异步只是调用RPC接口时为异步,执行获取结果的方法为同步,会阻塞当前线程直到接口返回结果。

【推荐】RPC消费者使用泛化的方式时,注意配置的id和代码参数名一样,才能正确注解到参数上。

<hsf:consumer id=”genericTestService” version=”1.0.0″ group=”test” interface=”cn.com.flaginfo.edas.demo.service.GenericTestService” generic=”true”/>

java代码:

@Autowired
private GenericService genericTestService;

【强制】RPC消费者使用泛化的方式时,如果接口方法没有参数,$invoke方法要传空数组对象,不能传null。

String version = (String)genericTestService.$invoke(“getGenericTest”, new String[]{}, new Object[]{});

异常处理规范

【强制】RESTful/http方式的api 开放接口必须捕获异常,并使用“错误码”。

【强制】服务类和跨项目调用的RPC生产者接口实现类必须捕获异常,并使用统一的Result方式,封 装 isSuccess()方法、“错误码”、“错误简短信息”。

说明:关于 RPC 方法返回方式使用 Result 方式的理由:

1)使用抛异常返回方式,调用方如果没有捕获到就会产生运行时错误。

2)如果不加栈信息,只是 new 自定义异常,加入自己的理解的 error message,对于调用 端解决问题的帮助不会太多。如果加了栈信息,因为RPC框架内部执行反射方法时,未捕获的异常会被封装成其他异常,最终业务自己定义的异常会被封装嵌套在其他2个异常内,在频繁调用出错的情况下会打印大量异常栈信息,而且数据序列化和传输的性能损耗也是问题。

日志规范

【强制】应用中不可直接使用日志系统(Log4j、Logback)中的 API,而应依赖使用日志框架 SLF4J 中的 API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger logger = LoggerFactory.getLogger(Abc.class);

【强制】对 trace/debug/info 级别的日志输出,必须使用条件输出形式。

例如

if (logger.isDebugEnabled()) {

   logger.debug(“Processing trade with userId: ” + userId + ” order : ” + order );
}

说明:logger.debug(“Processing trade with userId: ” + userId + ” order : ” + order ); 如果日志级别是 warn,上述日志不会打印,但是会执行字符串拼接操作,如果 order 是对象, 会执行 toString()方法,浪费了系统资源,执行了上述操作,最终日志却没有打印。

【推荐】谨慎地记录日志。生产环境禁止输出debug日志;有选择地输出info日志;如果使用 warn 来记录刚上线时的业务行为信息,一定要注意日志输出量的问题,避免把服务器磁盘撑爆,并记得及时删除这些观察日志。

说明:大量地输出无效日志,不利于系统性能提升,也不利于快速定位错误点。

【推荐】可以使用 warn 日志级别来记录用户输入参数错误的情况,避免用户投诉时,无所适从。注意日志输出的级别,error 级别只记录系统逻辑出错、异常等重要的错误信息。如非必要,请不要在非异常及错误场景打出error级别。

返回值规范

【强制】Http接口返回值统一封装为HttpResult,方便接口调用方统一解析返回结果、处理返回值状态。

【强制】RPC接口必须都有返回值,且统一封装为ServiceResult,方便调用方统一解析返回结果,处理异常信息。无返回值的返回类型写为ServiceResult<Void>

【强制】消费者调用RPC接口返回的ServiceResult<T>必须判断isSuccess()方法值,处理存在的返回值异常信息。

HttpResult

/**
 * HTTP接口返回对象封装
 */

public class HttpResult {

    /**
     * 返回错误结果封装
     * @param resCode 返回值代码
     * @param resMsg 返回值消息
     */
    public Map<String, Object> onFailure(String resCode, String resMsg) {

        Map<String, Object> result = new HashMap<String, Object>(2);
        result.put(“resCode”, resCode);
        result.put(“resMsg”, resMsg);
        return result;
    }

    /**
     * 返回正确结果封装
     * @param data 返回参数
     */
    public Map<String, Object> onSuccess(Map<String, Object> data) {

        Map<String, Object> result = new HashMap<String, Object>();
        result.put(“errcode”,“0”);
        result.put(“errmsg”, “ok”);
        if (data != null) {

            result.putAll(data);
        }
        return result;
    }
}

ServiceResult

/**
 * Service层返回对象封装
 */
public class ServiceResult<T>  implements Serializable{

    /**
     * 请求是否成功
     */
    private boolean success = false;
    /**
     * 返回值代码
     */
    private String resCode;
    /**
     * 返回消息
     */
    private String resMsg;
    /**
     * 返回结果
     */
    private T result;

    private ServiceResult() {

    }

    /**
     * 返回正确结果封装
     * @param result 返回结果
     * @param <T> 返回结果Class
     * @return 正确结果封装
     */
    public static <T> ServiceResult<T> onSuccess(T result) {

        ServiceResult<T> serviceResult = new ServiceResult<T>();
        serviceResult.success = true;
        serviceResult.result = result;
        serviceResult.resCode = “0”;
        serviceResult.resMsg = “ok”;
        return serviceResult;
    }

    /**
     * 返回错误结果封装
     * @param resCode 错误代码
     * @param resMsg 错误消息
     * @return 错误结果封装
     */
    public static <T> ServiceResult<T> onFailure(String resCode, String resMsg) {

        ServiceResult<T> item = new ServiceResult<T>();
        item.success = false;
        item.resCode = resCode;
        item.resMsg = resMsg;
        return item;
    }

    /**
     * 返回错误结果封装
     * @param resCode 错误代码
     * @return 错误结果封装
     */
    public static <T> ServiceResult<T> onFailure(String resCode) {

        ServiceResult<T> item = new ServiceResult<T>();
        item.success = false;
        item.resCode = resCode;
        item.resMsg = “failure”;
        return item;
    }

    public boolean hasResult() {

        return result != null;
    }

    public boolean isSuccess() {

        return success;
    }

    public T getResult() {

        return result;
    }

    public String getResCode() {

        return resCode;
    }

    public String getResMsg() {

        return resMsg;
    }

    @Override
    public String toString() {

        return “ServiceResult{” +
            “success=” + success +
            “, resCode='” + resCode + \’+
            “, resMsg='” + resMsg + \’+
            “, result=” + result +
            ‘}’;
    }
}

 

使用指南

上架和部署说明

登录

登录地址:https://signin.aliyun.com/flaginfo/login.htm

EDAS控制台入口

选择页面左边列表的《企业级分布式应用服务 EDAS》 或者页面中间偏下的《企业级分布式应用服务 EDAS》标签,进入EDAS控制台。

 

EDAS控制台

此页面简称为EDAS控制台,EDAS相关的资源管理,应用管理,配置管理,性能监控,任务调度,链路分析都集成在这里。

 

创建应用

点击应用管理→创建应用,输入应用相关信息,然后单击 下一步。

 

 

字段说明
应用运行环境:运行应用的容器 (Ali-Tomcat) 版本,默认是最新的版本
应用名称:应用名称(此服务名称),在所属主账号内不能重复
应用所在区域:选择华东1(目前我们EDAS的服务器都在华东1
应用健康检查:EDAS 定期访问该 URL,根据其响应状态,确定应用的存活状态,若不配置,EDAS 不进行应用的健康检查,但不影响应用的正常运行。
备注:该应用的描述性信息。

设置应用类型和网络类型

 

字段说明:

应用类型 选择 普通应用

网络类型 选择 经典网络

实例 选择 应用将要部署的实例

点击创建应用(此步奏之后,应用的容器便创建好了,之后还要上传war包或jar包)

部署应用

点击应用管理→需要部署的应用后边的操作(管理)→部署应用,上传jar包输入版本信息,设置完成后,单击 部署应用

 

 

 

 

部署应用参数说明:

文件上传方式:

上传 war 包或jar包:选择上传 war 包或jar包后,在下面上传 war 包或jar包右侧单击选择文件,打开本地文件夹,选择要部署的 WAR 包或jar包。

war 包或jar包地址:选择 war 包或jar包地址后,在下面 war 包或jar包地址右侧的文本框中输入定存放 war 包或jar包且可以访问的 URL 地址。

使用历史版本:使用历史版本:选择使用历史版本后,在下面历史版本的下拉框中选择要使用的历史版本。

发布目标分组:需要发布此应用版本的分组。

请填写版本:应用版本用于标识一次应用发布所使用的部署包的版本,能够帮助用户很好的区分每一次应用发布的部署包版本,并在回滚操作的时候,能够精准的跟踪到某一次发布。

注意:部署应用的时候,可以添加一个版本号或者文字描述,不建议使用 用时间戳作为版本号。

版本描述:对此 war 包/jar包版本进行描述。

历史版本(仅适用于使用历史版本的文件上传方式):在下拉框中选择要使用的历史版本。

启动应用

创建并部署应用成功后,在应用详情页面右上角单击 启动应用,启动应用。

应用启动后,页面右上角会提示 启动成功。应用中的实例的任务状态显示为 运行中。

 

查看启动日志

点击左运行日志→实时日志→双击catalina.out,即可查看启动日志

 

 

应用监控

监控大盘

登录 EDAS 控制台。

在左侧导航栏,单击 应用管理。

在应用列表中,单击需要监控的 应用名称。

在具体应用页面左侧导航栏中,选择 应用监控 监控大盘。

说明:包括 CPU、负载、内存、磁盘及网络,将鼠标悬停到监控图- 横坐标的某个点,可以查看该时间点的信息和状态数据。

 

基础监控

EDAS 从应用所运行的机器上采集数据,然后基于分析的结果提供 CPU、内存、负载、网络、磁盘五个主要指标的单机与集群视图。所有监控均以应用为单位进行数据的统计和处理。

注意:由于从数据的采集到分析存在一定的延时,所以 EDAS 无法提供百分之百的实时监控视图,目前的时延策略为2分钟。

查看集群或者单机统计视图的步骤为:

登录 EDAS 控制台,单击 应用管理,在 应用列表 中单击具体的应用。

在应用详情页面左侧的导航栏中选择 应用监控 基础监控,进入基础监控页面。

 

  基础监控页面默认监控最近半小时的分组数据,也可以通过选择时间间隔及单机数据页签监控其它时间间隔的分组数据和单机数据。

选择监控数据类型

监控的数据类型包括分组数据和单机数据两种。

这两种数据类型从不同维度监控相同的一些列指标,包括:

CPU 数据统计汇总:代表 CPU 的占用率,为 user 和 sys 占用率的和,其中分组数据的图示为该应用分组内所有机器占用率的平均值。

内存数据统计汇总:物理内存的总大小与实际使用大小,其中分组数据的图示为该应用分组内所有机器的总大小与总使用大小。

负载数据统计汇总:系统负载中的 1 min load 字段,其中分组数据中的图示为该应用分组内所有机器 1 min load 的平均值。

网络速度数据统计汇总: 网卡的写出与读入速度,如果机器上有多块网卡,该数据代表所有网卡名以“eth”开头的写出与读入速度的总和,其中分组数据中的图示为该应用分组内所有机器的平均值。

磁盘数据统计汇总:机器上所有挂载磁盘的总大小与实际使用大小,其中分组数据的图示为该应用分组内所有机器的总大小与总使用大小。

磁盘读写速度数据统计汇总:机器上所有挂载磁盘的读写速度大小总和,其中分组数据的图示为应用分组内所有机器改数据的平均值。

磁盘读写次数数据统计汇总:机器上所有挂载磁盘的读写次数(IOPS)总和,其中分组数据的图示为应用分组内所有机器改数据的平均值。

设置时间间隔

时间间隔包括半小时、六小时、一天和一周四种。

半小时:统计当前时间之前半个小时内的监控数据,是登录基础监控页面时的默认方式。数据统计点的时间间隔为 1 分钟,是 EDAS 所提供的最细的查询粒度。

六小时:统计当前时间之前 6 个小时内的监控数据,数据统计点的时间间隔为 5 分钟。

一天:统计当前时间之前 24 个小时内的监控数据,数据统计点的时间间隔为 15 分钟。

一周:统计当前时间之前 7 天内的监控数据,数据统计点的时间间隔为1小时,是 EDAS 提供的最长统计周期。

说明:

页面中的“开始时间”与“结束时间”,是当前视图所呈现的时间跨度;当选择其中一项时,对应的项会自动调整其值,如:选择“半小时”,结束时间选择 “2016年5月20日 12点00分00秒”时,开始时间会自动设置为 “2016年5月20日 11点30分00秒”。

设置完成后,监控的数据随选择的时间间隔自动进行更新。

 

服务监控

通过收集和分析在不同的网络调用中间件上的日志埋点,可以得到同一次请求上的各个系统的调用链关系,有助于梳理应用的请求入口与服务的调用来源、依赖关系,同时,也对分析系统调用瓶颈、估算链路容量、快速定位异常有很大帮助。

监控服务

登录 EDAS 控制台。

在左侧导航栏中,单击 应用管理

在应用列表中,单击要监控的 应用名称

在具体应用页面左侧的导航栏中选择 应用监控 > 服务监控

 

 

服务监控页面包含七个页签:

应用概要:展示所提供服务的总体情况和调用的服务情况。

我的入口:展示对外提供的 HTTP 入口列表。

提供的 RPC 服务:展示当前应用所提供的 RPC 的调用情况。

RPC 调用来源:展示当前应用所提供的 RPC 服务被哪些应用调用。

RPC 调用依赖:展示当前应用调用了哪些应用的服务。

访问数据库:展示对数据库的请求情况。

消息类型:MQ 消息等。

默认显示默认分组下的应用概要页签。

(可选)设置监控条件,单击 更新,更新监控数据。

最新:默认展示当前时间的数据情况,点击下拉箭头,可以手工选择时间。

order by:默认以 QPS 排序,点击下拉箭头,可以按耗时、错/S(一分钟平均出错的 QPS)进行排序。

结果数:默认显示10条结果,点击下拉箭头,可以设置展示数量,包括1、5、30、50、100和不限。

展现:默认以豆腐块图展现,也可以选择支持多图和表格作为展现形式。

单击监控图中某一列的具体指标,弹出自定义查询页面,查看该指标项的监控数据。

 

在指标区域中,选择不同指标,也可以监控不同组合的数据。

查看调用链

在监控服务过程中,可以监控该应用和其它应用的附件间的调用关系,同时也可以查看详细的调用链路。

在监控图中,单击调用的或被调用的服务右侧的 查看调用链,跳转到 链路分析 > 调用链查询 页面。

 

在调用链查询页面,可以查看该应用和(被)调用的服务间的调用链路。

 

点击TraceId会跳转到调用链详情页面,显示调用链详细信息

 

监控下钻应用

服务监控页面除了可以查询和该应用相关的调用链路,还可以下钻到相互依赖的应用上进行监控。

在 提供的 RPC 服务RPC 调用来源 或 RPC 调用依赖 等页签中,单击监控图上方 下钻 右侧的 来源应用被调用的服务 或 调用的服务 按钮,弹出下钻应用的监控页面。

监控下钻应用的数据。

 

全自动化测试方案

全链路压测方

详见:

https://www.aliyun.com/product/edas?spm=5176.10695662.746114.1.29c8530csNLY1M

https://www.aliyun.com/product/apsara-stack/doc?spm=5176.12021097.1218927.3.16e56015283E54

https://manage.aliyun.com/manage/view/cdu_document/product_zh/topic/EDAS_UserGuide_ManageAccount_9.2.3.html

 

 

今天的文章eda设计的基本流程_开发规范「建议收藏」分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/58908.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注