Post on 07-Jul-2015
description
企业应用架构
模块化、微服务与 Linux 容器技术
Lifan Yang
2014/10/21
RPRM 目前的模块组成
现行 RPRM 的模块依赖
新模块依赖
模块依赖关系:扁平 vs 立体
扁平关系:中心模块定义接口,所有模块通过中心接口模块间接依赖。优点:设计简单;缺点:无法反映实际依赖关系,不利于理解,可维护性差立体关系:接口分散在各模块中。缺点:设计较“复杂”;优点:可反映实际依赖关系。易于理解,可维护性强。
现行模块设计的其它问题
● 模块过多(50多个)● 模块责任不明● 模块之间耦合● 不易于扩展
非环形包依赖
环形包依赖(错误)
例子:存在环形依赖
public class Bill {
private Router router;
public Bill(Router router) {
this.router = router;
}
public String route() {
return this.router.route(this);
}
}
用回调解决环形依赖
若干场景
● 场景一:Provision 功能导致内存泄露● 场景二:NTLM 验证功能导致线程死锁● 场景三:DMA 短时间发送大量消息导致 TCP
连接数及线程耗尽● 场景四:同一版本中两个特性开发时间不一致,导致先开发完的特性不能先行发布
微服务
● 应用中的模块可以以进程(或其它单位),作为独立的服务运行
● 服务之间使用轻量、语言无关的协议进行通信
● 服务可以用不同的语言、框架开发
微服务图示
微服务与 SOA
● Java 嵌入式Web 容器、Play!、NodeJS 等技术的出现,使现在的服务可以比 SOA 时代更小巧灵活
● REST、JSON、Thrift、AMQP 等技术的出现,可以提供比 SOAP WS 更轻量、快速、可靠的跨进程通信
● Zookeeper 等分布式一致性存储技术为分布式环境提供了可靠的配置管理、分布式锁、Leader 选举解决方案
● Redis、MongoDB 等 NoSQL 提供了更好的分布式数据存储方案
微服务如何解决问题
● 内存溢出问题:独立运行的服务可以避免内存使用的相互影响(注)
● 线程死锁问题:独立运行的服务可以避免线程死锁的相互影响
● 大量消息问题:网络连接数的影响取决于服务运行的形式;线程影响同上
● 特性开发不同步问题:独立服务可独立发布
为什么不使用整体 HA?
Provision
MSA Monolithic HA
Provision ProvisionProvision
微服务的好处
● 异构性:每个服务可以使用,例如:不同版本的框架、不同版本的运行时、甚至是不同的语言
● 独立开发、测试和部署:IDE 加载应用更快、编译更快;可以独立进行集成测试和部署
● 按需伸缩:根据功能模块的不同需要,按需伸缩,而不是整体地、不加区分地伸缩
● 错误隔离:(前面例子已经看到)
进程间通信
● 中低响应度同步通信: REST
● 高响应度同步通信: Thrift、Protocol Buffers
● 一对一异步通信: RabbitMQ(AMQP)、Thrift
● Pub/Sub 通信: RabbitMQ、Redis
服务路由与注册
?
Service A
Service B
10.10.10.1
Service B
10.10.10.2
Service B
10.10.10.3
服务路由与注册
?
Service A
Service B
10.10.10.2
Service B
10.10.10.3
服务路由与注册
?
Service A
Service B
10.10.10.4
Service B
10.10.10.2
Service B
10.10.10.3
服务路由与注册
Service A: Watch$ etcdctl watch /foo-service --recursive
Serivce B: Set the data$ etcdctl set /foo-service/container2 localhost:2222 --ttl 20
localhost:2222
Service A: Get the notify$ etcdctl watch /foo-service --recursive
localhost:2222
多进程
● 资源隔离:端口冲突、运行时冲突● 资源限制:CPU、内存、磁盘、网络● 环境一致性
虚拟机
可以解决:资源隔离、资源限制等等问题,但就一点:
贵!
“贵”体现在哪?
● 环境贵:需要 VMware Server、OpenStack
、AWS EC2 等虚拟机服务器支持● 部署贵:部署一个虚拟机实例短则几分钟、长则几十分钟,甚至更长
● 运行成本贵:虚拟机虚拟全部计算机硬件,运行时性能损耗较大;每个虚拟机实例成本较高
容器技术
● 轻量“虚拟化”:可提供进程、磁盘、网络的资源隔离
● 使用 Linux 内核 cgroups 做资源限制;使用namespaces 做资源隔离
● 容器共享系统内核,无硬件虚拟化,比Hypervisor 虚拟技术效率高,速度快
容器技术 vs 虚拟机
容器技术 vs 虚拟机容器技术 虚拟机技术
占用磁盘空间 小,甚至几十KB(镜像层的情况) 非常大,上GB
启动速度 快,几秒钟 慢,几分钟
运行形态 直接运行于宿主机的内核上,不同容器共享同一个Linux内核
运行于Hypervisior上
并发性 一台宿主机可以启动成千上百个容器 最多几十个虚拟机
性能 接近宿主机本地进程 逊于宿主机
资源利用率 高 低
Docker 简介
● Docker 是一种容器技术,它由管理轻量级容器的引擎、客户端和AUFS文件系统三部分组成
● Docker 镜像可以一次编译,在各种 Linux 系统上(CentOS、Ubuntu...)和云主机上运行
● 如果把容器比作集装箱,Docker 就像它的名字,将镜像部署在各个平台上运行
● 容器技术已经有了十年左右大规模的使用,而 Docker 则极大推动了容器技术的普及
Docker 使用
hello world
运行 Redis:创建 Dockerfile
创建一个镜像
运行镜像
FROM ubuntu:12.10RUN apt-get updateRUN apt-get -y install redis-serverEXPOSE 6379ENTRYPOINT ["/usr/bin/redis-server"]
sudo docker run -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"
sudo docker build -t <your username>/redis .
sudo docker run -name redis -d <your username>/redis
Docker 与云计算
● 虚拟化:VMware产品线将全面支持 Docker
● 公有 IaaS:AWS EC2 和 Beanstalk 都支持部署 Docker
容器(注)● 私有 IaaS:OpenStack 从 Havana 开始引入了 Docker
Driver,从 Hypervisor 层面对 Docker 给与支持(注)● PaaS:CloudFoundry 和 OpenShift 都将以 Docker 作为运行时层
● 操作系统:CentOS 和 RHEL 都对 Docker 给予优化;出现了只是用 Docker 运行应用的操作系统 CoreOS 和Project Atomic
图景
Dockerfile Docker
Img RegQA
Private Public
谢谢