获得徽章 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可以帮助更好地从单体架构和集中式架构转型到分布式微服务架构收起
展开
评论
#青训营笔记创作活动#

2月9日 打卡day1
今日学习了限流的相关方法,链接附在下方。
限流是限制到达系统的并发请求数量,保证系统能够正常响应部分用户请求,而对于超过限制的流量,则通过拒绝服务的方式保证整体系统的可用性。限流是高并发场景下的常用方法之一,常用的限流方法有计数器、滑动窗口、漏桶、令牌桶等方法。这些方法在实际使用上各有优劣,需要结合使用场景具体问题具体分析,选择合适的限流方法
展开
评论
#青训营笔记创作活动#
2月7日 打卡day18
今日学习了Flowable
现在市面上主流的流程引擎有三个:Activiti、Flowable、Camunda。这三个各有特点:Activiti 目前是侧重云,他目前的设计会向 Spring Cloud、Docker 这些去靠拢。Flowable 核心思想还是在做一个功能丰富的流程引擎工具,除了最最基础的工作流,他还提供了很多其他的扩展点,我们可以基于 Flowable 实现出许多我们想要的功能(当然这也是小伙伴们觉得 Flowable 使用复杂的原因之一)。Camunda 相对于前两个而言比较轻量级,Camunda 有一个比较有特色的功能就是他提供了一个小巧的编辑器,基于 bpmn.io 来实现的(松哥之前已经发文讲过了)。如果你的项目需求是做一个轻巧的、灵活的、定制性强的编辑器,工作流是嵌入式的,那么可以选择 Camunda。
展开
评论
#青训营笔记创作活动#
2月5日 打卡day17
今日学习了分库分表
分库分表是分别的两个概念 ,通过一定的规则,将原本数据量大的数据库拆分成多个单独的数据库,将原本数据量大的表拆分成若干个数据表,使得单一的库、表性能达到最优的效果(响应速度快),以此提升整体数据库性能。因为数据库容量有限,连接数有限,单表容量有限,因而实际场景中为了提高性能,需要分库分表。
分库分表的核心就是对数据的分片(Sharding)并相对均匀的路由在不同的库、表中,以及分片后对数据的快速定位与检索结果的整合。
分库分表后需要使用一定的路由规则来找到数据,常见的有取模算法 、范围限定算法、范围+取模算法 、预定义算法。
分库分表存在分页、排序、跨节点联合查询,事务一致性,全局唯一的主键,多数据库高效治理,历史数据迁移等问题。
分库分表架构主要有两种模式:client客户端模式和proxy代理模式
展开
评论
#青训营笔记创作活动#
2月4日 打卡day16
今日学习了高并发场景的一些知识
秒杀其实是一直瞬时高并发的场景,为应对这种场景,一般通过以下几个方面入手设计系统:页面静态化、CDN加速、缓存、mq异步处理、限流、分布式锁。
页面静态化即活动页面绝大多数内容是固定的,只有到了秒杀时间点,并且用户主动点了秒杀按钮才允许访问服务端。且根据用户位置使用CDN(Content Delivery Network,即内容分发网络)加速。
秒杀按钮使用js文件控制,为了性能考虑,一般会将css、js和图片等静态资源文件提前缓存到CDN上,让用户能够就近访问秒杀页面。分布式锁可以解决缓存击穿的问题,下单功能做成mq异步处理。限流一般有基于nginx限流和基于redis限流两种方法。
展开
评论
#青训营笔记创作活动#
2月3日 打卡day15
今日学习了redis
redis是一款优秀的缓存中间件,在客户端与数据层之间作为缓存层来分担请求压力。redis的优点是完全基于内存操作,性能极高,读写速度快;支持高并发;支持主从模式,支持读写分离与分布式;具有丰富的数据类型与丰富的特性(发布订阅模式);支持持久化操作,不会丢失数据。缺点是数据库容量受到物理内存的限制,不能实现海量数据的高性能读写;相比关系型数据库,不支持复杂逻辑查询,且存储结构相对简单;虽然提供持久化能力,但实际更多是一个 disk-backed 功能,与传统意义上的持久化有所区别。
redis高性能的原因是完全基于内存;数据结构简单,操作方便,并且不同数据结构能够应对于不同场景;采用单线程(网络请求模块使用单线程,其他模块仍用了多线程),避免了不必要的上下文切换和竞争条件,也不存在多进程或多线程切换导致CPU消耗,不需要考虑各种锁的问题;使用多路I/O复用模型,为非阻塞I/O;本身设定了 VM 机制,没有使用 OS 的Swap,可以实现冷热数据分离,避免因为内存不足而造成访问速度下降的问题。
展开
评论
#青训营笔记创作活动#
2月2日 打卡day14
今天学习了加密相关的知识
非对称加密指加密和解密用到的不是同一个秘钥,而是两个不一样的秘钥,分别是公钥和私钥。公钥负责加密,私钥负责解密。公钥人人可得,私钥永远不泄露。
在HTTP层之上再加一层TLS层,目的就是为了做个加密,这就成了我们常说的HTTPS。
TCP握手后,HTTPS还需要经历两个阶段的加密。第一阶段是TLS四次握手,这一阶段主要是利用非对称加密的特性各种交换信息,最后得到一个"会话秘钥"。第二阶段是则是在第一阶段的"会话秘钥"基础上,进行对称加密通信。
TLS四次握手的过程中涉及到两对私钥和公钥。分别是服务器本身的私钥和公钥,以及CA的私钥和公钥。
展开
评论
#青训营笔记创作活动#
1月30日 打卡day13
今日学习了SQL语句相关的内容。
SQL语句室友客户端产生的,一般可以手动产生,或者由ORM框架产生。产生后去获取数据库连接,当网络连接建立成功后,也就等价于在MySQL中创建了一个客户端会话,经过验证用户名密码、查找空闲线程、获取当前登录用户的权限信息并授权等工作后,执行SQL语句的通道被打通。
接下来是执行过程:
1.先将SQL发送给SQL接口,SQL接口会对SQL语句进行哈希处理。
2.SQL接口在缓存中根据哈希值检索数据,如果缓存中有则直接返回数据。
3.缓存中未命中时会将SQL交给解析器,解析器会判断SQL语句是否正确,错误则抛出1064错误码及相关的语法错误信息,正确则将SQL语句交给优化器处理,进入第4步。
4.优化器根据SQL制定出不同的执行方案,并择选出最优的执行计划。
5.工作线程根据执行计划,调用存储引擎所提供的API获取数据。
6.存储引擎根据API调用方的操作,去磁盘中检索数据(索引、表数据....)。
7.发生磁盘IO后,对于磁盘中符合要求的数据逐条返回给SQL接口。
8.SQL接口会对所有的结果集进行处理(剔除列、合并数据....)并返回。

SQL语句的执行过程,实际上也就是MySQL的架构中一层层对其进行处理。
展开
评论
#青训营笔记创作活动#
1月23日 打卡day12
今日学习了MySQL的架构。
MySQL的整体架构从上往下看,依次会分为网络连接层、系统服务层、存储引擎层、以及文件系统层,往往编写SQL后,都会遵守着MySQL的这个架构往下走。
连接层:主要是指数据库连接池,会负责处理所有客户端接入的工作。
服务层:主要包含SQL接口、解析器、优化器以及缓存缓冲区四块区域。
存储引擎层:这里是指MySQL支持的各大存储引擎,如InnoDB、MyISAM等。
文件系统层:涵盖了所有的日志,以及数据、索引文件,位于系统硬盘上。
除此之外,MySQL的客户端可以使用各种语言编写的,客户端负责编写SQL,而服务端则负责SQL的执行与数据的存储。
展开
评论
#青训营笔记创作活动#
1月22日 打卡day11
今日学习了502问题排查的方法。
HTTP中5XX的状态码是服务器有问题的意思,但是服务器出问题了可能并不会返回状态码,所以说,一般情况下5xx的状态码其实并不是服务器返回给客户端的。它们是由网关返回的,常见的网关,比如nginx。
nginx网关充当中间层,帮助客户端与多个服务器通信,客户端直连nginx,再由nginx直连服务端。于是,当服务器发生异常时,nginx发送给服务器的那条TCP连接就不能正常响应,nginx在得到这一信息后,就会返回5xx错误码给客户端,也就是说5xx的报错,其实是由nginx识别出来,并返回给客户端的,服务端本身,并不会有5xx的日志信息。如果发现502,优先通过监控排查服务端应用是否发生过崩溃重启,如果是的话,再看下是否留下过崩溃堆栈日志,如果没有日志,看下是否可能是oom或者是其他原因导致进程主动退出。如果进程也没崩溃过,去排查下nginx的日志,看下是否将请求打到了某个不知名IP端口上。
展开
评论
#青训营笔记创作活动#
1月21日 打卡day10
今日学习了优秀后端都应该具备的开发好习惯:
1.注释尽可能全面,写有意义的方法注释
2.项目拆分合理的目录结构
3. 不在循环里远程调用、或者数据库操作,优先考虑批量进行。
4. 封装方法形参
5. 封装通用模板
6. 封装复杂的逻辑判断条件
7. 保持优化性能的嗅觉
8. 可变参数的配置化处理
9. 会总结并使用工具类
10. 控制方法函数复杂度
11. 在finally块中对资源进行释放
12.把日志打印好
13. 考虑异常,处理好异常
14. 考虑系统、接口的兼容性
15. 代码采取措施避免运行时错误
展开
评论
下一页
个人成就
文章被阅读 375
掘力值 23
收藏集
1
关注标签
2
加入于