@ApplicationPath("/")
public class MyApplication extends Application {
public MyApplication() {
}
}
微服务技术
SpringBoot开发框架
Vertx异步框架
容器技术和配套服务
和原有JavaEE技术的对比和结合使用
采用一组服务的方式来构建一个应用,服务独立部署在不同的进程中,不同服务通过一些轻量级交互机制来通信,例如 RPC、HTTP 等,服务可独立扩展伸缩,每个服务定义了明确的边界,不同的服务甚至可以采用不同的编程语言来实现,也可以使用不同的数据存储技术,由独立的团队来维护。
随着时间推移逐渐变大
敏捷开发和部署举步维艰
启动速度长,开发和生产效率受到极大影响
资源冲突时难以扩展
整体可靠性脆弱
不容易采用新的架构,技术或者编程语言
更小,更简单的应用
更容易理解和开发, 更快的构建和部署
避免了jar/classpath hell
更好的分布式协作:开发,部署,每个服务都可以扩展
错误隔离
避免了单一技术架构的风险
整个系统的架构和服务层面的架构
容易采用新技术
开发分布式系统的复杂性
进程间通信
需要处理局部失败问题
需要处理涉及到多个数据库的事务
测试分布式系统不易
部署和运维分布式系统非常复杂
需要管理涉及到多个服务的特性
海量用户和访问量
需要成千上万的机器协同工作
高效可靠的运维平台
传统企业级架构无法满足
单个机架,数量不多的集群服务能力
基准代码:一份代码,多份部署
依赖:显式地声明依赖关系
配置:在环境中存储配置信息,与语言和环境无关
后端服务:当作附加资源可以部署时更换
构建,发布,运行:发布时有唯一ID版本标示
进程:以一个或者多个无状态的进程运行
端口绑定:通过端口提供服务,监听发送至该端口的请求
并发:通过进程模型进行扩展
易处理:快速启动和优雅终止保证健壮性
开发环境和线上环境等价:尽可以的保持一致,缩小差异
日志:把日志当作事件流直接输出到标准输出中
管理进程:后台管理任务当作一次性进程运行
通用语言 (Ubiquitous language)
很好定义的模型和边界
单一职责
独立部署,可扩展和具有弹性
通过异步消息进行通信
拥有数据
不会直接暴露公有API
快速构建基于Spring框架的独立进程应用
通过Maven pom构建,组合多个starter
自由选择各个层次的实现,比如web容器可以选用tomcat/undertow等
利用SpringActuator提供产品上线监测的特性。
注解定义的配置项和配置文件,Coc约定优于配置
Tomcat, Jetty, undertow
WebMVC, Thymeleaf, Websocket
Spring Security
JPA, Spring Data, Mongo, Redis
JMS, RabbitMQ
Batch
@SpringBootApplication
@Configuration
@EnableAutoConfiguration
@ComponentScan
@EnableWebMvc
application.properties
yaml配置文件 application.yml
按照profile定义:app-production.properties
classpath路径上
包含相关技术的starter pom, 以及很多社区的starter
依赖定义,对应的配置项解析能力
可能快速的构建应用和使其运行
示例
spring-boot-starter-web
spring-boot-starter-data-rest
spring-boot-starter-security
spring-boot-starter-actuator
可监视点
/health /metrics /trace
/info /dump /env
/dump /shutdown
JMX / SSH
Auditing 审计
Logging
Config Server
Eureka (Service Registry)
Ribbon (Load Balancer)
Hystrix (Circuit Breakers)
Zuul (Intelligent Routing)
1.0.0.CR1
基于Wildfly-core 2.1
JBoss MSC作为微内核核心
Fraction片段组装而成
利用Maven的构建和打包能力
@ApplicationPath("/")
public class MyApplication extends Application {
public MyApplication() {
}
}
@Path("/")
public class EmployeeResource {
@Inject PersistenceHelper helper;
@GET @Produces("application/json")
public Employee[] get() {
return helper.getEntityManager().createNamedQuery("Employee.findAll",
Employee.class).getResultList().toArray(new Employee[0]);
}
}
可以运行基于JVM多种语言的响应式编程开发工具
Java
Ruby
Javascript
设计成可扩展和非阻塞的
基于Netty网络库,类似NodeJs的设计思路
Json消息作为结构数据体
Verticle异步模型
内建的多线程支持
Event bus (消息通道,本地或者远程)
Point to point
Public/Subscribe
Request/Response
微服务方式部署
传统的一个连接一个线程模式,如Tomcat
工作线程阻塞,后来的线程必须等待
一个线程处理所有请求,如NodeJs
如果工作线程被阻塞,整个队列需要等待
等待前面的工作完成(无法最好发挥多核优势)
组合上述优点,对于长时间阻塞工作采用线程池
多个EventLoop
组件是单线程模型
"Actor-style"并发方式
和Java的并发模式不同
无须使用synchronized, volatile, 加锁等
告别线程竞争开发和调试大坑
TCP/UDP - Client/Server
HTTP(s)/REST
WebSocket
RxJava
SockJS
轻量级 Vert.x core核心
扩展
Web
数据访问 (JDBC, mongoDB, redis…)
Security (Auth / JWT / OAuth2)
Reactive (RxJava)
Clustering (Hazelcast / JGroups)
public void start() throws Exception {
vertx.createNetServer().connectHandler(sock -> {
Pump.pump(sock, sock).start();
}).listen(1234);
System.out.println("Echo server is now listening");
}
public void start() throws Exception {
vertx.createHttpServer().requestHandler(req -> {
req.response().putHeader("content-type", "text/html").
end("<html><body><h1>Hello from vert.x!</h1></body></html>");
}).listen(8080);
}
public void start() throws Exception {
Router router = Router.router(vertx);
router.route().handler(routingContext -> {
routingContext.response().putHeader("content-type", "text/html").end("Hello World!");
});
vertx.createHttpServer().requestHandler(router::accept).listen(8080);
}
Observer<HttpServer> observer = new Observer<HttpServer>() {
@Override public void onNext(HttpServer o) {
}
@Override public void onError(Throwable e) {
}
@Override public void onCompleted() {
}
};
Handler<AsyncResult<HttpServer>> handler = RxHelper.toFuture(observer);
HttpClient client = vertx.createHttpClient(new HttpClientOptions());
HttpClientRequest request = client.request(HttpMethod.GET, 8080, "localhost", "/the_uri");
request.toObservable().subscribe(
response -> {
// Process the response
},
error -> {
// Could not connect
}
);
request.end();
看作是轻量级VM
拥有自己的进程空间
拥有自己的网络接口
以root身份运行
和主机共享内核
以docker容器为资源分割和调度的基本单位
封装整个软件运行环境
为开发者和系统管理员设计的
用于构建,发布和运行分布式应用的平台
pid 进程编号
uts 主机名与域名
ipc 信号量,消息队列和共享缓存
network 网络设备,网络站,端口等
mount 挂载点
user 用户和用户组
持续部署和测试
跨云平台支持
环境标准化和版本控制
高资源利用率和隔离
容器跨平台性与镜像
应用镜像仓库,方便易用
Copy-on-write 写时复制机制
堆叠式
union 联合文件系统 AUFS, overlayfs
snapshot 快照文件系统 BTRFS, ZFS
copy-on-write 块设备 Device-mapper
存在于多个容器上的文件或者文件夹
不同容器之间共享和重用
对数据卷的操作会马上生效
不会影响到镜像本身
类似mount操作
含有启动Docker容器所需文件系统结构内容
按照一定层次结构叠加而成
存放在registry仓库中
公有仓库Docker Hub (hub.docker.com)
repository名称 username/repo_name
登录账户
使用镜像 pull拉取操作
commit,提交变更的部分
build,完成一个新镜像的构建
push,制作镜像并上传至仓库
docker0网桥
veth pair连接各个容器网络
通过网桥转发到eth0网卡上
可以使用brctl查看和管理网桥
添加一些iptables规则
四种网络模式:bridge, host, container, none
容器间可以使用 --link通信
一个管理docker容器的平台
高级特性
容器分组
负载均衡
自动扩展,应用弹性伸缩
源于Google实践项目
Pod 一组容器
Label 标签用于标记pod
Replication controller 副本控制器
Service 提供相同服务的Pod
etcd 元数据服务
Kubelet 节点上的代理,负责Pod的创建,修改,监控,删除等
Proxy pod负载均衡代理
cAdvisor 资源监控和性能分析
Scheduler 集群中的调度齐,调度分配pod到工作节点
Controller Manager 集群内部的管理控制中心
API server 提供了资源对象的操作入口
若干个docker容器构成的容器组
创建,调度,管理的最小单元
pod里的容器共享网络和存储
pid/ipc/uts namespace也共享
方便传统应用的部署
决定pod同时运行多少个副本
通过预先定义的pod模板来创建pod
对pod的数量和健康状况通过副本选择器进行监控
使用场景
弹性伸缩,修改副本数
滚动更新,灰度发布
应用的多版本release跟踪
看作一组提供相同服务的pod对外访问接口
代理来确保IP地址固定
为多个pod做负载均衡,路由策略(默认轮转)
建立iptables规则
通过DNS服务的发现形式
负载均衡
健康检查
请求路由
请求响应重写
缓存
压缩
SSL处理
负载均衡策略
round-robin 轮询
IP hash 根据IP地址的hash值来分布负载
最小连接方法
失败检测
会话持久性
TCP负载均衡
HTTP keepalive连接
HTTP SSL
HTTP/2
Websocket
Docker和Kubernetes
利用操作系统层,网桥和iptables等
入口点反向代理
Nginx分发 (Undertow采用相同的设计思路)
apache modules成熟也足够强大
应用层的负载均衡和路由
Netflix Ribbon/Zuul
根据应用需要和架构需求,搭配使用
Routing 路由
Service aggregation 服务聚合
Security (Encryption,Signing) 加密签名等
Protocol conversion 协议转换
Legacy adapters 适配器
Payload transformation 报文格式变换
Service catalog 服务目录
对外API暴露需要安全防护
认证 (密码,token,指纹,二次验证)
授权 (三方服务)
加解密,不被篡改
审计 (记录每一步操作)
统一管理
LDAP/Kerberos
SAML
OAuth2
Social Login (Github, Twitter)
KeyCloak - SSO server中心管理点
和应用服务器集成
微服务分布式,需要有工具来检测依赖性以及性能
后台处理流程,收发消息等用图示方式显示
跟踪信息的元数据:trace, span, log(annotation)
AOP 实现思路,埋点,javaagent
Zipkin开源项目
代码事务执行效率分析
错误率,每分钟请求数
服务器监控
报警和报告
可视化呈现
Elasticsearch 搜索平台,也是一个分布式文档数据库
配置成集群方式
多个节点的分布式系统
分片和副本
Logstash 日志的收集和分析
agent用来监控和过滤收集日志
Kibana 日志分析提供友好的web界面
服务注册和发现
软负载均衡和容错
服务监控和统计
容量评估和流量控制
上线审批和下线通知
服务路由
服务编排
协作流程
服务黑白名单
服务依赖关系
权限控制,角色授权
服务分层架构
调用链跟踪
故障导流和隔离
自动部署
服务降级
优先级调度
自动测试
服务超时控制
服务降级,权重动态调整
多版本管理
容器和资源调度
健康度状态检测
2000年左右,C/C++编写的Corba程序
每个服务一个独立进程
IDL定义接口,生成框架代码并编译成可执行程序
命名服务,集群和容错
消息,事务,安全
历史重演
基于Web容器,部署应用
是否需要分布和组件的线程安全性,选择EJB还是CDI
JavaEE7非常完备和庞大,33个子规范
适用于企业级应用开发,应用对事务性有较高的需求
一键式的部署和方便管理运维
对数字敏感度高的应用,事务要求也高
财务软件
企业业务系统
保持一致性
访问量不是很大,安全性要求高
最终一致性适用的场景
跨越企业组织需要优化业务流程
技术上采用异步消息等机制
线程安全
对象池
远程访问
RMI/IIOP
Web Services
MDB/JMS
Timer/Scheduled events
安全集成
Java分布式调用
同步/异步方法都可以支持
选择合适的数据传输粒度
MDB配合消息使用
应用服务器实现支持集群/容错等高级特性
SpringRemoting
HttpInvoker
Hessian
Dubbo
Thrift
gRPC
消息是解耦的主要设计方式
分布式消息
按协议传输内容
实现事务最终一致性
编程语义和本地做到统一,如RxJava
进程内的通知机制
Event/Listener
异步响应式编程,不方便单步调试,但整体效率高
是相似的设计方案
Spring框架在于实现具体化
CDI在于API和设计思路的统一
CDI非常强大,有Apache DeltaSpike外延项目
DDD设计,每个大型应用应当有自定义的CDI组件
Hibernate是ORM的经典成功项目
JPA API总结了通用的实体和关系数据库之间的映射
需要对NoSQL/NewSQL有支持
SpringData高效简洁的对主流数据库支持
其他可以选择方案Hibernete OGM / JDO
解析到数据结构,而不是实体对象类中
分布式数据库
分布式缓存
分布式的文件系统
支持分库分表,按照维度分片
设计时需要仔细衡量事务的重要性
打包后的SpringBoot应用20M以上
NodeJs的应用各种依赖也很多
"微"不是体积上的微小,而是限制在领域边界内
各层都需要打包到应用中,或者在环境路径中
服务层,数据层,表现层都得有
服务自理,具有安全,管理性,日志等方方面面的内容
所有的微服务体积总和远大于单一的应用服务器加上部署包
应用逻辑中状态信息保存的位置 - Http/Json
Native界面:MFC/.NET/Cocoa
经典的MVC模板:JSP/SpringMVC/Freemaker等
Ios/Android原生界面
JavaSwing/EclipseSWT
JQuery/Bootstrap - AngularJS - ReactNative
JSF - GWT- JavaFX
针对不同的应用和系统规模
强事务的要求
用户量和并发访问量
用户访问界面类型
运维团队的规模和技术能力
架构师和开发者的系统思维
容器是运行应用的环境,需要被管理有所限制
Docker是操作系统级别的容器
JVM中的容器(多租户能力的支持)
应用服务器的分布扩展,就变成了微服务治理体系
进程内和跨进程通信
分布式通信
需求没变,如安全,监控,日志等,分布式统一管理
参考了借鉴了以下公司的公开资料
Nginx
Netflix
Redhat
Pivotal
Lightbend
Thanks!