
获得徽章 2
- #青训营笔记创作活动#
2月19日 打卡day11
今日学习了502问题排查的方法。
HTTP中5XX的状态码是服务器有问题的意思,但是服务器出问题了可能并不会返回状态码,所以说,一般情况下5xx的状态码其实并不是服务器返回给客户端的。它们是由网关返回的,常见的网关,比如nginx。
nginx网关充当中间层,帮助客户端与多个服务器通信,客户端直连nginx,再由nginx直连服务端。于是,当服务器发生异常时,nginx发送给服务器的那条TCP连接就不能正常响应,nginx在得到这一信息后,就会返回5xx错误码给客户端,也就是说5xx的报错,其实是由nginx识别出来,并返回给客户端的,服务端本身,并不会有5xx的日志信息。如果发现502,优先通过监控排查服务端应用是否发生过崩溃重启,如果是的话,再看下是否留下过崩溃堆栈日志,如果没有日志,看下是否可能是oom或者是其他原因导致进程主动退出。如果进程也没崩溃过,去排查下nginx的日志,看下是否将请求打到了某个不知名IP端口上。展开评论点赞 - #青训营笔记创作活动#
2月18日 打卡day10
今日学习了优秀后端都应该具备的开发好习惯:
1.注释尽可能全面,写有意义的方法注释
2.项目拆分合理的目录结构
3. 不在循环里远程调用、或者数据库操作,优先考虑批量进行。
4. 封装方法形参
5. 封装通用模板
6. 封装复杂的逻辑判断条件
7. 保持优化性能的嗅觉
8. 可变参数的配置化处理
9. 会总结并使用工具类
10. 控制方法函数复杂度
11. 在finally块中对资源进行释放
12.把日志打印好
13. 考虑异常,处理好异常
14. 考虑系统、接口的兼容性
15. 代码采取措施避免运行时错误展开评论点赞 - #青训营笔记创作活动#
2月17日 打卡day9
今日学习:
作者尝试抓baidu的数据包,发现不能成功,于是开始找原因。
首先是因为他访问的是HTTPS协议的baidu.com。HTTP协议里的Host和实际发送的request body都会被加密,所以没办法通过http.host进行过滤。HTTPS经过了TCP握手和TLS加密握手流程,之后就是两段加密信息和TCP挥手流程。HTTPS握手的过程中会先通过非对称机密去交换各种信息,其中就包括3个随机数,再通过这三个随机数去生成对称机密的会话秘钥,后续使用这个会话秘钥去进行对称加密通信。如果能获得这三个随机数就能解密HTTPS的加密数据包。三个随机数,分别是客户端随机数(client random),服务端随机数(server random)以及pre_master_key。前两个,是明文,第三个是被服务器公钥加密过的,在客户端侧需要通过SSLKEYLOGFILE去导出。通过设置SSLKEYLOGFILE环境变量,再让curl或chrome会请求HTTPS域名,会让它们在调用TLS库的同时导出对应的sslkey文件。这个文件里包含了三列,其中最重要的是第二列的client random信息以及第三列的pre_master_key。第二列client random用于定位,第三列pre_master_key用于解密。展开评论点赞 - #青训营笔记创作活动#
2月16日 打卡day8
今日学习了写出漂亮代码的45个小技巧:
1、规范命名
2、规范代码格式
3、写好代码注释
4、try catch 内部代码抽成一个方法
5、方法别太长
6、抽取重复代码
7、多用return
8、if条件表达式不要太复杂
9、优雅地参数校验
10、统一返回值
11、统一异常处理
12、尽量不传递null值
13、尽量不返回null值
14、日志打印规范
15、统一类库
16、尽量使用工具类
17、尽量不要重复造轮子
18、类和方法单一职责
19、尽量使用聚合/组合代替继承
20、使用设计模式优化代码
21、不滥用设计模式
22、面向接口编程
23、经常重构旧的代码
24、null值判断
25、pojo类重写toString方法
26、魔法值用常量表示
27、资源释放写到finally
28、使用线程池代替手动创建线程
29、线程设置名称
30、涉及线程间可见性加volatile
31、考虑线程安全问题
32、慎用异步
33、减小锁的范围
34、有类型区分时定义好枚举
35、远程接口调用设置超时时间
36、集合使用应当指明初始化大小
37、尽量不要使用BeanUtils来拷贝属性
38、使用StringBuilder进行字符串拼接
39、@Transactional应指定回滚的异常类型
40、谨慎方法内部调用动态代理的方法
41、需要什么字段select什么字段
42、不循环调用数据库
43、用业务代码代替多表join
44、装上阿里代码检查插件
45、及时跟同事沟通展开评论点赞 - #青训营笔记创作活动#
2月15日 打卡day7
今日学习
在我们通常的印象里,UDP是比TCP快的,但是作者通过这篇文章打破了我们的这种印象。
在使用socket编程的时候,我们可以选择使用TCP或者UDP协议,二者对于丢包的处理是不一样的,UDP一般不处理丢包的情况,TCP则会使用重传机制、流量控制机制、滑动窗口机制、拥塞控制机制、分段机制、乱序重排机制进行处理,这一步骤上会花费时间,因此大部分情况下TCP是慢于UDP的。
但由于UDP本质是内核提供的一个最小网络传输功能,大多数人不会直接在项目中使用UDP,往往会在UDP的基础上做各种不同程度的应用层可靠性保证。比如王者农药用的KCP,以及最近很火的QUIC(HTTP3.0),其实都在UDP的基础上做了重传逻辑,实现了一套类似TCP那样的可靠性机制。虽然选择了使用UDP,但一般还是会在应用层上做一些重传机制的。
对于UDP+重传的场景,如果要传超大数据包,并且没有实现分段机制的话,那数据就会在IP层分片,一旦丢包,那就需要重传整个超大数据包。而TCP则不需要考虑这个,内部会自动分段,丢包重传分段就行了。这种场景下,其实TCP更快。展开评论点赞 - #青训营笔记创作活动#
2月14日 打卡day6
今日学习
我们在工作中往往会遇到这些问题:遇到的 Bug 百度没有结果怎么办?中文翻译文献模棱两可怎么办?如何寻找外文文献?读不懂英文文档中的复杂句子等等。
作者分享了他解决这些问题的“笨”方法,所谓“笨”实际上是勤能补拙,大智若愚。
作者会抄录遇到的复杂问题的英文bug,和文档中的复杂句子,在出差途中或其他闲暇时光拿出来阅读理解,深入研究。遇到bug百度没有结果的时候,可以Google、必应、或者StackOverflow。在翻译文献时遇到模棱两可的翻译,在谷歌、百度、韦氏、剑桥、牛津五家线上词典的围攻下将你的疑问降低到零。搜索英文文献时,应该直接搜索英文,而不是中文翻译。对于英文长难句,要学会分析句子,拆分句子,慢慢读懂理解。展开评论点赞 - #青训营笔记创作活动#
2月13日 打卡day5
今日学习了Kafka的科普文章
Kafka包括消息系统、存储系统和流式处理平台。一个典型的 Kafka 体系架构包括若干 Producer、若干 Broker、若干 Consumer,以及一个 ZooKeeper 集群,如图所示。其中 ZooKeeper 是 Kafka 用来负责集群元数据的管理、控制器 的选举等操作的。Producer 将消息发送到 Broker,Broker 负责将收到的消息存储到磁盘中,而 Consumer 负责从 Broker 订阅并消费消息。
在 Kafka 中还有两个特别重要的概念——主题(Topic)与分区(Partition)。Kafka 中的消息以 topic 题为单位进行归类,生产者负责将消息发送到特定的 topic (发送到 Kafka 集群中的每一条消息都要指定一个主题),而消费者负责订阅主题并进行消费。
在 Kafka 的消费理念中还有一层消费组(Consumer Group))的概念,每个消费者都有一个对应的消费组。当消息发布到主题后,只会被投递给订阅它的每个消费组中的一个消费者。
主题和分区都是提供给上层用户的抽象,而在副本层面或更加确切地说是 Log 层面才有实际物理上的存在。同一个分区中的多个副本必须分布在不同的 broker 中,这样才能提供有效的数据冗余。
Kafka 为分区引入了多副本(Replica)机制,通过增加副本数量可以提升容灾能力。同一分区的不同副本中保存的是相同的消息(在同一时刻,副本之间并非完全一样),副本之间是一主多从的关系,其中 leader 副本负责处理读写请求,follower 副本只负责与 leader 副本的消息同步。副本处于不同的 broker 中,当 leader 副本出现故障时,从 follower 副本中重新选举新的 leader 副本对外提供服务。Kafka 通过多副本机制实现了故障的自动转移,当 Kafka 集群中某个 broker 失效时仍然能保证服务可用。展开评论点赞 - #青训营笔记创作活动#
2月12日 打卡day4
怎么样才能在用户不做任何操作的情况下,网页能收到消息并发生变更。作者通过这个问题引入,介绍了HTTP协议和websocket协议。
问题的一种常见解决方法是网页的前端代码里不断定时发HTTP请求到服务器,服务器收到请求后给客户端响应消息,达到一种伪服务器推的形式。但是这样会占用带宽,而且用户会感觉到卡顿。
还有一种方法是长轮询,将HTTP请求超时设置的很大,比如30s,在这30s内只要服务器收到了扫码请求,就立马返回给客户端网页。如果超时,那就立马发起下一次请求。这样可以解决扫码登陆这种简单情景的卡顿问题。本质上,其实还是客户端主动去取数据。
TCP是全双工的,基于TCP的HTTP协议却是半双工的,而另一种基于TCP的应用层协议websocket是全双工的。网页游戏使用的就是websocket协议。建立TCP连接后,统一使用HTTP协议发报文,如果想要升级成websocket协议就加上一个特殊的header头。升级websocket协议的过程也是一次TCP握手的过程。
websocket完美继承了TCP协议的全双工能力,并且还贴心的提供了解决粘包的方案。它适用于需要服务器和客户端(浏览器)频繁交互的大部分场景。比如网页/小程序游戏,网页聊天室,以及一些类似飞书这样的网页协同办公软件。展开评论点赞 - #青训营笔记创作活动#
2月11日 打卡day3
今天学习的这篇文章讲解了电脑如何知道自己IP的过程。
电脑的IP可以手动设置,还可以通过DHCP自动分配。DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)。通过DHCP,在联网之后可以自动获取到本机需要的IP地址,子网掩码还有路由器地址。
DHCP工作分为以下几个流程:
1.DHCP Discover:在联网时,本机由于没有IP,也不知道DHCP服务器的IP地址是多少,所以根本不知道该向谁发起请求,于是索性选择广播,向本地网段内所有人发出消息,询问"谁能给个IP用用"。
2.DHCP Offer:不是DHCP服务器的机子会忽略你的广播消息,而DHCP服务器收到消息后,会在自己维护的一个IP池里拿出一个空闲IP,通过广播的形式给回你的电脑。
3.DHCP Request:你的电脑在拿到IP后,再次发起广播,就说"这个IP我要了"。
4.DHCP ACK:DHCP服务器此时再回复你一个ACK,意思是"ok的"。你就正式获得这个IP在一段时间(比如24小时)里的使用权了。后续只要IP租约不过期,就可以一直用这个IP进行通信了。
第一次联网要经过四个过程,如果曾经连过这个网,机器会记录你上次使用的IP,再次连接时优先使用原来的那个IP,因此只需要经历第三第四阶段。DHCP是应用层协议,考虑到需要支持广播功能,底层使用的是UDP协议,而不是TCP协议。DHCP分配下来的IP是有可能跟某台手动配置的IP地址重复的。DHCP得到IP之后还会发3次无偿ARP通告,在确认没有冲突后开始使用这个IP。展开评论点赞 - #青训营笔记创作活动#
2月10日 打卡day2
今日学习
正好最近在学习Go语言,看到这样一篇文章给我很多帮助。
作者建议,学习go语言应刷官方文档,首先搞清楚概念,再手敲代码并写注释,了解实现功能,学有余力可将自己的见解写成文章,帮助后来的学习者。
作者认为语言学习不是难点,难点在于思维转换。如客户端是UI驱动设计,那么服务端就是数据驱动设计,服务端开发的关键在于能否设计出合理的数据库表。
目前的服务端开发分布式微服务架构是主流趋势,微服务架构可以实现业务和应用之间的解耦,越来越多的企业采用分布式微服务架构进行业务转型。
DDD (Domain Driven Design):领域驱动设计。DDD可以帮助更好地从单体架构和集中式架构转型到分布式微服务架构收起展开评论点赞