生产就绪(Production Ready)
架构的可运维性主要和配置,监控,部署这些环节相关。其中监控包括日志监控,调用链监控。
经典软件工程阶段
互联网软件交付阶段
什么是生产就绪
SpringBoot如何实现分环境配置
Staffjoy环境
配置中心选项比较
动态配置更新
Apollo vs SpringCloud Config vs K8s ConfigMap
| Apollo | SpringCloud | K8s ConfigMap | |
|---|---|---|---|
| 配置界面 | 统一界面管理,不同环境和集群配置 | 无,通过Git操作 | Cli或Dashboard |
| 配置存储 | DB | Git | Etcd |
| 配置生效时间 | 实时推送+应用配合 | 近实时+应用配合 | 近实时+应用配置 |
| 动态配置 | 支持,实时推送 | 复杂+MQ | 支持发布更新 |
| 版本管理 | UI支持发布历史和回滚 | 无,通过Git操作 | 无,需自己管理 |
| 灰度发布 | 支持 | 不支持 | 支持灰度发布 |
| 授权/审计/审核 | UI操作,修改和发布权限分离 | 需要通过Git仓库设置 | K8s平台部分支持 |
| 实例配置监控 | 可见哪些客户端配置生效 | 不支持 | 可查询容器环境变量 |
| 客户端支持 | 原生Java/.Net,提供API,支持Spring标注 | Spring应用+标注支持 | 语言无关 |
参考样例
Apollo动态配置
https://github.com/ctripcorp/apollo-use-cases
SpringCloud集中配置
https://github.com/sqshq/piggymetrics
服务监控工具对比
监控平台的演进历史
CAT vs Zipkin vs Skywalking
| CAT | Zipkin | Apache Skywalking | |
|---|---|---|---|
| 调用链可视化 | 有 | 有 | 有 |
| 聚合报表 | 非常丰富 | 少 | 较丰富 |
| 服务依赖图 | 简单 | 简单 | 好 |
| 埋点方式 | 侵入 | 侵入 | 非侵入,运行期字节码增强 |
| VM指标监控 | 好 | 无 | 有 |
| 告警支持 | 有 | 无 | 有 |
| 多语言支持 | Java/.Net | 丰富 | Java/.Net/NodeJS/PHP自动,Go手动 |
| 存储机制 | MySQL(报表),本地文件/HDFS(调用链) | 可选in memory,MySQL,ES(生产),Cassandra(生产) | H2,ES(生产) |
| 社区支持 | 主要在国内,点评/美团 | 文档丰富,国外主流 | Apache支持,国内社区好 |
| 国内案例 | 点评,携程,陆金所,拍拍贷 | 京东,阿里定制不开源 | 华为,小米,当当,微众银行 |
| APM | Yes | No | Yes |
| 祖先源头 | eBay CAL | Google Dapper | Google Dapper |
| 同类产品 | 暂无 | Uber Jaeger,SpringCloud Sleuth | Naver Pinpoint |
| 亮点 | 企业级生产,报表丰富 | 社区生态好 | 非侵入,Apache背书 |
| 不足 | 用户体验一般,社区一般 | APM报表能力弱 | 时间不长,文档一般,仅限中文社区 |
Skywalking
https://skywalking.apache.org/
Skywalking Java Agent支持库
https://skywalking.apache.org/docs/#JavaAgent
Zipkin
Jaeger
Staffjoy依赖监控图
日志监控
结构化日志和审计日志
https://github.com/jacek99/structlog4j
import com.github.structlog4j.IToLog;import lombok.Builder;import lombok.Data;@Data@Builderpublic class LogEntry implements IToLog {private String currentUserId;private String companyId;private String teamId;private String authorization;private String targetType;private String targetId;private String originalContents;private String updatedContents;@Overridepublic Object[] toLog() {return new Object[] {"auditlog", "true","currentUserId", currentUserId,"companyId", companyId,"teamId", teamId,"authorization", authorization,"targetType", targetType,"targetId", targetId,"originalContents", originalContents,"updatedContents", updatedContents};}}
import com.github.structlog4j.ILogger;import com.github.structlog4j.SLoggerFactory;static ILogger logger = SLoggerFactory.getLogger(AccountService.class);LogEntry auditLog = LogEntry.builder().authorization(AuthContext.getAuthz()).currentUserId(AuthContext.getUserId()).targetType("account").targetId(account.getId()).updatedContents(account.toString()).build();logger.info("created account", auditLog);
集中异常监控和Sentry
官网:https://sentry.io
开源仓库:https://github.com/getsentry/sentry
Sentry云服务的使用
客户端配置
@Beanpublic SentryClient sentryClient() {SentryClient sentryClient = Sentry.init(staffjoyProps.getSentryDsn());sentryClient.setEnvironment(activeProfile);sentryClient.setRelease(staffjoyProps.getDeployEnv());sentryClient.addTag("service", appName);return sentryClient;}
发送异常监控日志
public void handleError(ILogger log, String errMsg) {log.error(errMsg);if (!envConfig.isDebug()) {sentryClient.sendMessage(errMsg);}}
EFK & Prometheus & Skywalking + Kubernetes集成架构
EFK + K8s
Prometheus + K8s
Skywalking + K8s

