0.1 业务代码n大禁忌(面向错误去设计)
1、严禁信任任何入参
• 严禁:入参对象不做空值检查
• 严禁:入参数组不做越界检查
• 严禁:分页参数不设逻辑上、下限,如页数、每页数量
2、严禁为了代码性能不写try-catch
• 严禁主业务流程不做try-catch保护
• 严禁for/while循环内不做try-catch保护
3、严禁关键代码逻辑不打log
• 严禁:return的决策不打log
• 严禁:第三方接口调用不打log
• 严禁:被捕获的异常模块不打log
4、严禁catch模块吞掉异常栈和关键信息
5、严禁代码没有格式逻辑、没有注释
0.2数据库n大禁忌(面向风险去设计)
1、严禁工程师直接操作线上数据库
• 最高禁忌
• DROP
• TRUNCATE
• ALTER TABLE
• 次高禁忌
• DELETE
• UPDATE
• 如果有必要操作,必须在晚上12点之后操作
2、严禁没有/建错索引的SQL操作
• 严禁:忘记建索引
• 严禁:以“现在数据量小”为借口不建索引
3、严禁业务代码的一个SQL中存在两张表
• 严禁:表连接
• 严禁:子查询
4、严禁在for/while等循环中有SQL操作
• 循环中SELECT,需要放到循环开始前,使用SELECT * FROM order_item WHERE id IN(……)代替
• 循环中的UPDATE/INSERT,需要放到循环结束后,批量提交
5、严禁一个SQL操作或返回超过3000条记录,比如:
• 严禁:SELECT * FROM order_item;(必须加LIMIT 3000)
• 严禁:SELECT * FROM order_item WHERE id IN(1……3001)(IN的id数量不得超过3000)
• 严禁:UPDATE order_item SET status=100 WHERE id IN(1……3001)(IN的id数量不得超过3000)
• 严禁:INSERT INTO order_item VALUES(……),(……)(后面的值超过3000条)
6、严禁在线上数据库做全表遍历
• 会破坏数据库的缓存数据,直接影响性能
7、严禁COUNT/SUM语句被直接、频繁调用
• 如果有必要使用,必须结合缓存使用
• 最好的方案是有单独的计数、加总表
8、严禁WHERE条件中使用LIKE语句
• 如果有必要使用,必须保证前缀固定,如name LIKE '胡%'
9、严禁WHERE条件中的字段使用函数或被计算,比如
• 严禁:SELECT * FROM order_item WHERE amount / 100 > 1;
• 严禁:SELECT * FROM order_item WHERE DATE(create_time) = ‘2017-01-01’;
10、严禁WHERE条件中出现三个不定字段,比如
• 严禁:SELECT * FROM order_item WHERE amount > 100 AND create_time > ‘2017-01-01’ AND status > 0;
• 多个不定字段无法应用索引,最多容忍两个不定字段,但性能很差
11、严禁业务表、运营表、统计表耦合在一起
12、其他一些好的实践
• 不使用LIMIT M,N实现分页,比如
• 不建议:SELECT * FROM order_item LIMIT 100,20;
• 建议的做法是:SELECT * FROM order_item WHERE id > 12345 LIMIT 20;
• 不使用NULL值
• 小表不做物理删除,做逻辑删除;大表做物理删除,并建del表做备份
• 频繁写的字段和几乎不修改的字段,分表存储
• 不写复杂的SQL,复杂的SQL要写FORCE INDEX
0.3 服务稳定n大禁忌(面向崩溃去设计)
1、严禁基础服务缺失监控
• 严禁:没有系统参数监控的服务(磁盘、CPU、内存、连接数等)
• 严禁:没有存活状态监控的服务(端口)
• 严禁:没有业务逻辑监控的服务(未处理任务数)
2、严禁RPC接口调用不设超时时间
• 严禁:JDBC不设超时时间
• 严禁:HTTPClient不设超时时间
• 严禁:任何RPC调用接口不设超时时间
3、严禁接口调用缺失崩溃保护
• 严禁:接口调用连续失败,仍然继续调用
4、严禁基础服务不做逻辑上限保护
• 严禁:消息服务不做收件人频率、数量限制
5、严禁高并发请求直接进入业务逻辑
• 务必用java Concurrent包的ThreadPool去承接