获得徽章 1
#青训营笔记创作活动#
2023/2/12 打卡 day12
502问题怎么排查?
HTTP状态码
TCP是基于数据流的协议,传输数据时,并不会为每个消息加入数据边界,直接使用裸的TCP进行数据传输会有"粘包/拆包"问题。因此需要用特地的协议格式去对数据进行解析。于是在此基础上设计了HTTP协议。

于是就需要设计一套HTTP状态码,用来标识这次HTTP请求响应流程是否正常。通过这个可以影响浏览器的行为。比方说一切正常,那服务端返回个200状态码,前端收到后,可以放心使用响应的数据。但如果服务端发现客户端发的东西异常,就响应个4xx状态码,意思是这是个客户端的错误,4xx里头的xx可以根据错误的类型,再细分成各种码,比如401是客户端没权限,404是客户端请求了一个根本不存在的网页。反过来,如果是服务器有问题,就返回5xx状态码。一般情况下5xx的状态码其实并不是服务器返回给客户端的。它们是由网关返回的,常见的网关,比如nginx。

屏蔽掉具体有哪些服务器的代理方式就是所谓的反向代理。反过来,屏蔽掉具体有哪些客户端的代理方式,就是所谓的正向代理。而这个中间层的角色,一般由nginx这类网关来充当。

- HTTP状态码用来表示响应结果的状态,其中200是正常响应,4xx是客户端错误,5xx是服务端错误。

- 客户端和服务端之间加入nginx,可以起到反向代理和负载均衡的作用,客户端只管向nginx请求数据,并不关心这个请求具体由哪个服务器来处理。

- 后端服务端应用如果发生崩溃,nginx在访问服务端时会收到服务端返回的RST报文,然后给客户端返回502报错。502并不是服务端应用发出的,而是nginx发出的。因此发生502时,后端服务端很可能没有没有相关的502日志,需要在nginx侧才能看到这条502日志。

- 如果发现502,优先通过监控排查服务端应用是否发生过崩溃重启,如果是的话,再看下是否留下过崩溃堆栈日志,如果没有日志,看下是否可能是oom或者是其他原因导致进程主动退出。如果进程也没崩溃过,去排查下nginx的日志,看下是否将请求打到了某个不知名IP端口上。
展开
评论
#青训营笔记创作活动#
2023/2/11 打卡day11
如果把网络原理倒过来看,从无到有,一切都清晰了(上)

从单机到互联:本质是通信问题
数据传输方式:电路交换、报文交换、分组交换
电路交换:
最简单的连接两台相隔遥远的计算机的办法是分配一条专用通信(也就是一条专用的物理通路),而这就是电路传输方式。在电路交换中如果多台计算机之间互联,两两之间互联都需要拉线,那需要的电线也太多了。

于是就来到了两个思想,一个是转发,另一个是标识;它们是网络设计的核心问题,因为它们是一个网络扩大的基础。

转发的思想其实很简单,试想我们有A、B、C三台计算机,A和C并没有相连,而是经过了B。那么A计算机可以不可以先发到B计算机,再让B计算机帮我们转发C计算机呢。

标识的思想是,如果只是两台计算机,那么我们很清楚通信双方就是A在和B之间的通信(也就是相当明确数据是谁发送,以及是谁接收)。因此有了 MAC 地址

集线器(Hub)
计算机工程领域的任何问题都可以通过增加一个中间层来解决。所以我们可以加多一个中间设备,也就是集线器(Hub)。集线器是一层设备,(对应OSI网络模型,集线器就是工作在物理层),集线器将每台计算机之间连接在一起,所以它的每个接口仅仅简单地转发比特,意味着收到即转发(也就是收到1转会发1,收到0就转发0)。

交换机
交换机属于二层设备(对应OSI网络模型,也就是在数据链路层)。交换机比起集线器,实现了数据的全双工的通信,例如:A计算机在发送的时候,同时也可以进行数据的接收,在这个链路上的数据也不再会产生冲突。

报文交换
那么为了解决电路交换的“占线”问题,报文交换将每个用户发送的数据拆分成多个更小的部分数据,这些更小的数据携带着标识,起始点和目的地。那么不管是多少用户是否占着线,就需要存储-转发,只要拼凑汇聚成一个完整的数据。

分组交换
分组交换的思想源于报文交换,也采用存储转发的原理,但不同的是分组交换的最小信息单位是分组,而报文交换则是一个个报文。分组加速了数据在网络中的传输,一个分组的存储与前一个分组转发可以并行,所以本质分组交换也是存储转发,可以说让报文更加有组织,转发也更加迅速。

路由器是三层设备(对应OSI网络模型在网络层),所以路由器所连接的范围更广,网络和网络之间的连接就是通过路由器
展开
评论
#青训营笔记创作活动#
2023/2/10 打卡 day10
优秀后端都应该具备的开发好习惯

1.注释尽可能全面,写有意义的方法注释
对于接口方法的注释,应该包含详细的入参和结果说明,有异常抛出的情况也要详细叙述;类的注释应该包含类的功能说明、作者和修改者。;如果是业务逻辑很复杂的代码,真的非常有必要写清楚注释。

2.项目拆分合理的目录结构
如果服务过多,应该根据不同的业务进行划分,比如订单、登陆、积分等等。也可以根据不同的业务划分模块,比如建一个moudles包,然后按订单、登陆等业务划分,每个业务都有自己的controller、service、mapper、entity。

3. 不在循环里远程调用、或者数据库操作,优先考虑批量进行。远程操作或者数据库操作都是比较耗网络、IO资源的,所以尽量不在循环里远程调用、不在循环里操作数据库,能批量一次性查回来尽量不要循环多次去查。

4. 封装方法形参
如果你的方法参数过多,要封装一个对象出来。

5. 封装通用模板

6. 封装复杂的逻辑判断条件

7. 保持优化性能的嗅觉
比如避免创建非必要的对象、异步处理、使用缓冲流,减少IO操作等等。

8. 可变参数的配置化处理
比如用户多少天没登录注销、运营活动,不同节日红包皮肤切换、订单多久没付款就删除等等。对于这些可变的参数,不用该直接写死在代码。优秀的后端,要做配置化处理,你可以把这些可变参数,放到数据库一个配置表里面,也可以放到项目的配置文件或者apollo上。

9. 会总结并使用工具类。
我们既要会用工具类,更要学会自己去总结工具类。比如去文件处理工具类、日期处理工具类等等

10. 控制方法函数复杂度
你的方法不要写得太复杂,逻辑不要混乱,也不要太长。一个函数不能超过80行。写代码不仅仅是能跑就行,而是为了以后更好的维护。

11. 在finally块中对资源进行释放

12.把日志打印好
一般情况,方法入参、出参需要打印日志,异常的时候,也要打印日志等等

13. 考虑异常,处理好异常

14. 考虑系统、接口的兼容性

15. 代码采取措施避免运行时错误
优秀的后端开发,应该在编写代码阶段,就采取措施,避免运行时错误,如数组边界溢出,被零整除,空指针等运行时错误。
展开
评论
下一页
个人成就
文章被点赞 2
文章被阅读 1,176
掘力值 189
收藏集
2
关注标签
10
加入于