1 | { |
json 转化Map
json 转化Map
- 正常的fastjson和sf.json是无法的几行代码之内将json转化成Map
- 当时Gson就可以满足当前的需求
1 | @Data |
1 | public static final <T> T toObject(String jsonString, TypeReference<T> type) { |
2 2018 0127 补充
在使用Gson的时候,发现不能格式化带有int的json字符串。报错如下:
示例json
1
2
3
4
5
6
7
8
9
10
11
12
13
143: {
"id": 3,
"name": "背叛国家罪",
"open": false,
"pId": 2,
"title": "背叛国家罪"
},
4: {
"id": 4,
"name": "分裂国家罪",
"open": false,
"pId": 2,
"title": "分裂国家罪"
},解决方案
使用fastjson的类库进行格式化
1
JSON.parseObject(str, new TypeReference<Map<Integer, Bean>>(){});
灰度方案
大型应用的发布或者部署一般都需要制定特定的发布策略圈定发布范围发起变更来试错,从而减少因为不可预见的缺陷引发的故障影响面。
在技术方案评审的时候,对于复杂的需求,一定要考虑到系统升级发布方案,特别是涉及到配置项结构,数据库表模型,API变更的,需要考虑好灰度时,新旧版本的兼容性。复杂的需求,灰度往往是一个周期较长的过程,需要考虑好长时间的新旧版本,是否会出现不一致的场景已经应对方案。
错误的方案会导致即使发布经过了灰度流程,但是也不能发现问题,甚至有可能灰度本身反而会引起线上问题。
【最佳实践】
- 灰度方案设计时要注意是否向前兼容。
- 对于向前不兼容的场景,在设计灰度方案时要结合业务特性,使得灰度流量不要逃逸到正常机器上。如在营销工具升级中,可以按照商品分流,同一件商品要么都在灰度工具,要么都在旧工具。
- 涉及到写数据的灰度,如果不能做到向前兼容,可以通过数据加version,来保证新版本的数据由新逻辑处理。
- 灰度方案要有可逆向方案,
冗余备份相关
设计篇-冗余备份
工程学里有一个叫冗余备份的模型,在工程领域,航空领域,计算机领域大规模的都有应用。
比如航空领域里民航飞机一定会是两个引擎, 两份操作系统。计算机领域里,我们的同城双机房,单元化异地多机房都是为了应对单点故障风险。为了提升系统的高可用性,在取得成本投入与高可用保障的平衡前提下,尽可能的对最核心的系统依赖做多份冗余。我们在做日常需求中,为了满足功能的实现,往往会引入很多跨进程的外部依赖,每引入一个依赖就多一个故障点。
一些特别重要的功能,比如像用户下单支付、淘宝交易,由于这些功能对系统的高可用性要求极高,满足可用性的收益远远大于做冗余备份所付出的成本。
最佳实践
对应用的外部依赖进行整理,依赖最小化,重要依赖组件(如 MQ)增加冗余备份机制。
回滚方案验证
回滚的能力一般是由发布系统提供,当发布系统不具备回滚能力或者发布场景很复杂时,需要额外增加回滚方案的设计。
无论是系统自带的回滚能力,还是额外增加回滚方案,往往都不在整个上线发布的主流程中,不容易引起研发或者测试同学的重视。
如果在发布过程中遇到了问题,而没有经过验证的回滚方案,往往会导致原本应该很快通过回滚解决的问题,因为回滚不能及时执行造成问题升级,或者回滚的逻辑错误引起了更大的问题。
比如系统自带的回滚能力,如果平时没有实际使用过,在实际执行回滚操作的时候,发现回滚操作的执行逻辑和自己预期的逻辑不一致,或者缺少权限,导致回滚不能及时执行下去。或者理解错误了回滚的逻辑,以为系统执行的是全量回滚,但实际只回滚了增量部分,而增量部分的回滚,不能解决问题。
如果是未验证的回滚方案,在执行回滚的时候,会出现回滚逻辑并不是发布逻辑的逆操作,或者有的回滚方案,不能简单的逆操作能够解决,反而引起更大的线上问题。
【最佳实践】
研发同学在首次使用发布系统正式发布之前,需要先熟悉整个发布系统的功能,包括回滚的操作。
通过对测试版本的回滚操作,熟悉整个回滚流程,回滚逻辑。如果有相应的权限,需要提前申请好对应的权限,从而做到在真正需要执行回滚操作的时候,能够快速正确的完成版本回滚,及时止损。
复杂业务发布上线,需要把回滚方案纳入技术方案评审,功能测试的范畴。在正式发布上线前,需要对回滚也做一次预演,以确保回滚方案是正确的。
如果发布系统做了较大的改动,需要把回滚功能纳入测试范畴,回滚逻辑要具备连续性,特使是在权限控制上,要和原来保持一致。避免发布系统的改版,引起原来可以正操操作的回滚变更不可执行,延误问题的修复时间。
软件设计
设计是把一种设想通过合理的规划,周密的计划,通过各种感觉形式传达出来的过程。设计是将目标更好变现的过程。回到软件设计上来,就体现在如何将软件高度抽象,解耦以达到分而治之的过程。
设计是如此重要,我们既要具备对事物的抽象,解耦能力,又要能够从细节上作把控,做到大处着眼,小处着手。
对于方法论,软件设计领域也诞生了很多软件设计思想,比如面向过程设计
,面向对象设计
,面向服务设计
,面向消息设计
,面向失败设计等
,每种思想也都是在企业软件发展不同阶段解决某个领域或某一类的问题,没有好与坏的区别。
任何一点点的故障都可能带来严重的后果,因此面向失败设计显得尤为重要。我们需要横向从网络,dns,cdn,软负载,中间件,容器,存储,数据库等维度去梳理沉淀经验,也需要从纵向运维发布,监控报警,管控平台,调度,环境部署等维度梳理。 以下常用的参考指标:
- 编码设计 模块,服务,字段等设计的时候,需要考虑命名的可读性,见名知意,避免产生歧义。 接口设计需要满足开闭原则。
- 分布式设计 需要考虑一致性,避免脑裂问题产生。
- 缓存设计 确定命中率指标的前提下,需要持续观察未命中数据特征,特别是无效的查询,容易穿透缓存,命中数据库。
- 容量设计 自身稳态及尖刺容量评估确定的前提下,做好容量保护相应措施,比如限流,降级,隔离等
- 依赖设计 做好强弱依赖梳理,避免核心功能依赖非核心系统,非核心流程节点,能走异步最好走异步。
- 日志设计 系统日志尽可能异步化,尽量避免无效日志,控制台日志输出
- 监控设计 关键监控项及SLA的指标必须要做监控,监控项尽可能覆盖全,同时要做到有效报警,不要让大量无效报警淹没有价值的报警信息。
- 权限设计 本着够用原则,避免出现大权限,大账号,如果避免不了,需要做天花板限制。
表结构设计 分库分表需要考虑热点数据问题,时刻关注表的数据量大小
日期格式化(YYYY/MM/dd)
日期格式化时,yyyy表示当天所在的年,而大写的YYYY代表是week in which year(JDK7之后引入的概念),意思是当天所在的周属于的年份,一周从周日开始,周六结束,只要本周跨年,返回的YYYY就是下一年。另外需要注意:
- 表示月份是大写的M;
- 表示分钟则是小写的m;
- 24小时制的是大写的H;
- 12小时制的则是小写的h。
正例:表示日期和时间的格式如下所示:
new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);