阿里云企业级互联网架构实践系列(1)

微服务架构

微服务架构开源技术选型的重点在于如何合理的利用微服务,如下为通用的微服务架构图,每个环节都是微服务的核心部分。

image.png

网关集群:数据的聚合、实现对接入客户端的身份认证、防报文重放与防数据篡改、功能调用的业务鉴权、响应数据的脱敏、流量与并发控制等 业务集群:一般情况下移动端访问和浏览器访问的网关需要隔离,防止业务耦合 Local Cache:由于客户端访问业务可能需要调用多个服务聚合,所以本地缓存有效的降低了服务调用的频次,同时也提示了访问速度。本地缓存一般使用自动过期方式,业务场景中允许有一定的数据延时。 服务层:原子服务层,实现基础的增删改查功能,如果需要依赖其他服务需要在Service层主动调用 Remote Cache:访问DB前置一层分布式缓存,减少DB交互次数,提升系统的TPS DAL:数据访问层,如果单表数据量过大则需要通过DAL层做数据的分库分表处理。 MQ:消息队列用来解耦服务之间的依赖,异步调用可以通过MQ的方式来执行 数据库主从:服务化过程中毕竟的阶段,用来提升系统的TPS

EDAS

1.1 EDAS产品概述

企业级分布式应用服务(EDAS,Enterprise Distributed Application Service)是企业级互联网架构解决方案的核心产品,充分利用阿里云现有资源管理和服务体系,引入中间件成熟的整套分布式计算框架(包括分布式服务化框架、服务治理、运维管控、链路追踪和稳定性组件等),以应用为中心,帮助企业级客户轻松构建并托管分布式应用服务体系。

EDAS 支撑了整个阿里巴巴99%以上的大规模应用系统,其中涵盖了包括会员、交易、商品、店铺、物流和评价在内的所有在线核心系统,在稳定性、可靠性等多个维度具有独特的优势。

1.2 开发规范

配置中心(哪些配置项适合放)

为避免敏感信息泄密,从安全角度考虑,所以不建议放入 数据库配置, redis 配置之类。

建议放入需要在系统运行时动态修改的配置。比如:

  1. 程序需要通过一个flag 来判断是否需要执行一段代码。这个flag需要按照不同的环境或者不同时间段设置不同的值。

微服务拆分

  1. 微服务拆分并不是越细越好,粒度大小一个系统 3-8个人开发维护比较合适

  2. 微服务拆分应该考虑到代码的复用程度,对应会被高度复用的代码可以拆分成服务。如:规则校验。

  3. 对性能要求很高的功能点可以单独拆分成独立的微服务。

接口定义

  1. 接口通过HTTP 协议进行通信

  2. 理想条件下:一个集合对应一个数据库表,一个资源对应数据库的一行记录

  3. 不要暴露所有的资源操作比如:对应用户的删除操作不应该暴露给别的服务。

  4. 通过GET/books 方法获取资源列表,GET/books/1 获取单个资源。post 方法 创建资源:POST/books { "id":3, "name":"book"}。 delete 方法删除资源 DELETE /books/3, put方法更新资源。PUT /books/1 {"id":1,"name":"b1"}

  5. 使用JSON 作为消息传递的载体。

  6. 定义统一返回体 包括:code, message, T(泛型的消息体)。

  7. 返回体中的数据应与请求体数据保持一致,请求体应该是返回体子集(POST 时ID, PUT 时候的 update_time,不包含在内)

  8. 版本:

a. 通过 url 字段:http://api/vi/*

b. Accept header : Accept: application/json+v1 如果没有带版本自动访问最后版本

c. 自定义 header : X-API-Version: 1

限流降级

业务日志

  1. 日志输出是必要的字段: 时间戳,微服务,类,方法,业务名,

  2. 日志统一通过 | 进行分隔

微服务命名、接口命名

  1. 服务名不能包含下划线“_”

  2. 服务名最好便于理解

  3. 接口名称建议按照接口业务逻辑命名,见名知意。

无状态

  1. 不能把中间值或状态保存到内存或者本地文件中

  2. 对应一定需要状态的服务一定要把状态保存在这个微服务之外(数据库)。

1.3、FAQ

1.3.1 EDAS产品

1.3.1.1开发问题

6.1.1.1 如何注册到轻量级配置中心

6.1.1.2 如何使用轻量级配置中心的配置功能

6.1.1.3 edas环境下如何使用JUnit单元测试

由于edas应用的启动依赖于pandora 容器所有需要在Junit 测试类上面添加如下配置引入pandora 容器的启动

    @RunWith(PandoraBootRunner.class)

    @DelegateTo(SpringJUnit4ClassRunner.class)

    // 加载测试需要的类,一定要加入 Spring Boot 的启动类,其次需要加入本类。

    @SpringBootTest(classes = {ProviderApplication.class, JUnitTest.class })

    @Component

6.1.2 使用问题

6.1.2.1 如何处理服务启动后分布式服务总线应用列表无法显示

1、如果应用列表没有数据,不能说明应用无法注册到分布式服务总线,而是应用启动失败,或者EDAS鉴权配置有问题 2、检查应用启动日志,查看是否正常启动。 如果抛出其他异常导致无法启动需要联系业务同学确认。 如果没有报错需要确认EDAS_SERVICE_ID 环境变量是否过长, 不能超过36。

6.1.2.2 轻量级配置中心无法开启,开启时一闪就自动关闭

分发轻量级配置中心的时候,通过压缩文件分发,不要copy 解压后的文件夹。

6.1.2.3 如何处理服务启动后分布式服务总线服务列表为空

如果分布式服务总线的 服务列表是空的,就说明这个微服务没有注册到分布式服务总线 应用正常启动后(通过启动日志判断,出现pandora started说明启动完成), 查看 /etc/resolv.conf 确保EDAS的nameserver 放在首位。 查看 /home/admin/logs/vipsrv-logs/vipclient.log 中 如果有 code 403 access denied. 说明是容器所在宿主机的时间没有同步。需要联系云操系统的同事进行时间同步。时间同步后重启容器就可以注册成功。 如果有 error code 500 需要检查dncs-server 服务是否正常。

6.1.2.4 如何检测dncs-server服务是否正常

登录edas 物理机 docker ps|grep dncs-server docker exec -it docker_id bash cd /home/admin/bin 运行sh chekc_dncs.sh 如果 check_dncs.sh 运行异常说明dncs-server出现问题。

6.1.2.5 如何处理dncs-server服务的异常

登录edas 物理机

docker ps|grep dncs-server

docker exec -it docker_id bash

cd /home/admin/bin

运行sh chekc_dncs.sh

如果 check_dncs.sh 运行异常说明dncs-server出现问题

出现异常后可以进行 docker restart docker_id 重启dncs-server 容器,容器重启后大概需要3-7分钟启动dncs-server 的业务,可以使用/home/admin/bin/check_dncs.sh 检查是否启动完成

6.1.2.6 如何判断dncs-server服务的异常的原因

登录edas 物理机 docker ps|grep dncs-server docker exec -it docker_id bash cd /home/admin/bin 运行sh chekc_dncs.sh 如果 check_dncs.sh 运行异常说明dncs-server出现问题 dmesg |grep java 如果出现Out of memory: Kill process xxxx(java) 说明 dncs-server 进程由于OOM被linux 系统kill

6.1.2.7 注册到edas中不集群之间的服务是否可以互相调用

edas 鉴权体系的隔离不同账户之间不可能互相访问 不同集群使用不同的k8s集群做实现,不同k8s 集群的网络是不可以相通的

6.1.2.8 edas 负载均衡的机制是如何做的

如果使用HSF协议,HSF协议内部兼容了服务的负载均衡 如果使用spring cloud 框架下的RESTful 协议,由spring cloud 的Ribbon组件提供负载均衡

6.1.2.9 服务调用失败的重试机制如何实现

如果使用spring cloud 框架下的RESTful 协议,由spring cloud 的Ribbon组件重试,可以在application.properties 中配置ribbon 的重试策略

6.1.2.10 在国网环境下出现fail to get diamond-server serverlist! 如何处理

出现问题的如下:显示无法解析主机的情况下,一般是网络问题。

image.png
image.png

排查过程如下:

  1. 检查一下 容器启动时容器的环境变量的EDAS_DNS 是否填写正确

  2. 正确的EDAS_DNS 地址是 docker ps|grep dns-server, 2个容器中的一个

  3. 如果配置的DNS 正确,检查 容器文件:/etc/resolv.conf 中 EDAS_DNS 必须配置在第一行,如果没有配置说明客户使用问题,需要找客户确认原因。

  4. 如DNS 配置正确,还是无法ping通域名时,则需登录到dns-server容器中查看在dns-server中是否可以ping通。 http://configcenter.edas.sgcloud_dsb.com http://fileserver.edas.sgcloud_dsb.com

  5. 如果在dns-server 中无法ping 通需要找阿里进行协助排查 (重启dns-server 容器有可能恢复 dns-server 异常)

  6. 如果在dns-server 中可以ping 通上述域名, 说明客户的网络环境有问题。

6.1.2.11 服务注册不上

1.先确定是服务本身的问题还是环境的问题,辨别方法为: 如果是单个服务注册不上,那就是服务本身有问题; 如果是所有的服务都注册不上,则是环境问题 2.检查云服务中心和edas系统的时间差,看其是否在30S以内 3.查看服务运行日志和dncs的日志,从日志中查看原因

6.1.2.12 DNCS不断自动重启

1.检查ark-metadb数据库的主备是否同步 2.查看dncs内存是否升级过,如果没有,则可以先升级 3.手动修改容器内的业务脚本,看能否恢复,操作方法如下: (1).docker cp {container_id}:/home/admin/bin/start_dncs.sh ./ (2).编辑./start_dncs.sh,将第四行的#去掉 (3).docker cp start_dncs.sh {container_id}:/home/admin/bin/start_dncs.sh (4).稍等一分钟左右,即可进入容器了:docker exec -it {container_id} bash (5).再次编辑/home/admin/bin/start_dncs.sh,将第四行的#重新加上 (6).执行脚本 sh /home/admin/bin/start_dncs.sh

6.1.2.13 DNCS容器启动时提示 no sandbox present

修复dncs-server方法: 1. docker network connect --ip={容器IP} {容器所属网络名称} {容器ID} 2. docker restart 容器ID

6.1.2.14 服务概率性的调用不成功,重启服务本身后可以恢复正常

现象如下图

image.png

排查步骤: 1.检查服务所在的网络是不是稳定的 2.在服务的启动参数中将dns的ip换成另外一个,多测试几次,看是否正常 3..看一下客户的服务的fileserverip,是用的域名还是ip地址,如果是ip地址,就换成另外一个,重启服务后看看是不是正常的 4.检查edas环境中将cai-fs、dns、dncs这三个组件的运行状态,可将自检脚本都执行一遍,看看有没有哪个容器有异常的 5.检查这三个组件的容器的内存、cpu占有率等情况

你可能感兴趣的:(阿里云企业级互联网架构实践系列(1))