diff --git a/Chapter1 - iOS/1.74.md b/Chapter1 - iOS/1.74.md index e00c293..19a9428 100644 --- a/Chapter1 - iOS/1.74.md +++ b/Chapter1 - iOS/1.74.md @@ -4,7 +4,7 @@ App 的性能问题是影响用户体验的重要因素之一。性能问题主要包含:Crash、网络请求错误或者超时、UI 响应速度慢、主线程卡顿、CPU 和内存使用率高、耗电量大等等。大多数的问题原因在于开发者错误地使用了线程锁、系统函数、编程规范问题、数据结构等等。解决问题的关键在于尽早的发现和定位问题。 -本篇文章着重总结了 APM 的原因以及如何收集数据。APM 数据收集后结合数据上报机制,按照一定策略上传数据到服务端。服务端消费这些信息并产出报告。请结合[姊妹篇](https://github.com/FantasticLBP/knowledge-kit/blob/master/Chapter1%20-%20iOS/1.80.md), 总结了如何打造一款灵活可配置、功能强大的数据上报组件。 +xf本篇文章着重总结了 APM 的原因以及如何收集数据。APM 数据收集后结合数据上报机制,按照一定策略上传数据到服务端。服务端消费这些信息并产出报告。请结合[姊妹篇](https://github.com/FantasticLBP/knowledge-kit/blob/master/Chapter1%20-%20iOS/1.80.md), 总结了如何打造一款灵活可配置、功能强大的数据上报组件。 diff --git a/Chapter1 - iOS/1.94.md b/Chapter1 - iOS/1.94.md new file mode 100644 index 0000000..54a09bf --- /dev/null +++ b/Chapter1 - iOS/1.94.md @@ -0,0 +1,15 @@ +# APM + +## 启动时间的监控和治理 +- https://everettjf.github.io/2018/08/24/most-simple-task-queue-model/ +- https://github.com/izhangxb/GMTC/blob/master/全球移动技术大会GMTC%202017%20PPT/手淘iOS性能优化探索%20.pdf +- https://mp.weixin.qq.com/s/Kf3EbDIUuf0aWVT-UCEmbA +- http://yulingtianxia.com/blog/2016/10/30/Optimizing-App-Startup-Time/ +- https://www.jianshu.com/p/c14987eee107 +- https://time.geekbang.org/column/article/85331 +- https://punmy.cn/2018/06/18/15278496835424.html +- https://www.shangmayuan.com/a/a14fb820d1bc4457b018bf7b.html + + +> 我知道可以借助三方工具类BSBacktraceLogger获取主线程调用栈([BSBacktraceLogger bs_backtraceOfMainThread];),然后定时0.01秒计算各方法的调用耗时。但是具体不知道该怎么计算啊,望老师指点! +作者回复: 连续相同的堆栈,将其时间相加就是那个堆栈方法的耗时。 \ No newline at end of file diff --git a/Chapter5 - Network/5.5.md b/Chapter5 - Network/5.5.md new file mode 100644 index 0000000..7c415bf --- /dev/null +++ b/Chapter5 - Network/5.5.md @@ -0,0 +1,62 @@ +# iOS 端底层网络错误 + +> 本篇文章主要记录在 iOS 侧,一些底层网络问题的产生和解决。包括一些 socket 的疑难杂症 + + +## 典型案例 + +### 1. Socket 断开后会收到 SIGPIPE 类型的信号,如果不处理会 crash + +同事问了我一个问题,说收到一个 crash 信息,去 mpaas 平台看到如下的 crash 信息 + +![2021-04-06-NetworkFatlError.png](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/2021-04-06-NetworkFatlError.png) + +看了代码,显示在某某文件的313行代码,代码如下 + +![2021-04-06-NetworkFatlError.png](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/2021-04-06-NetworkFatalError2.png) + +Socket 属于网络最底层的实现,一般我们开发不需要用到,但是用到了就需要小心翼翼,比如 Hook 网络层、长链接等。查看官方文档会说看到一些说明。 + +当使用 socket 进行网络连接时,如果连接中断,在默认情况下, 进程会收到一个 `SIGPIPE` 信号。如果你没有处理这个信号,app 会 crash。 + +Mach 已经通过异常机制提供了底层的陷进处理,而 BSD 则在异常机制之上构建了信号处理机制。硬件产生的信号被 Mach 层捕捉,然后转换为对应的 UNIX 信号,为了维护一个统一的机制,操作系统和用户产生的信号首先被转换为 Mach 异常,然后再转换为信号。 + +Mach 异常都在 host 层被 `ux_exception` 转换为相应的 unix 信号,并通过 `threadsignal` 将信号投递到出错的线程。 + +![Mach 异常处理以及转换为 Unix 信号的流程](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/2020-05-19-BSDCatchSignal.png) + +有2种解决办法: + +- Ignore the signal globally with the following line of code.(在全局范围内忽略这个信号 。缺点是所有的 `SIGPIPE` 信号都将被忽略) + + ```objective-c + signal(SIGPIPE, SIG_IGN); + ``` + +- Tell the socket not to send the signal in the first place with the following lines of code (substituting the variable containing your socket in place of `sock`)(告诉 socket 不要发送信号:SO_NOSIGPIPE) + + ```c++ + int value = 1; + setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, &value, sizeof(value)); + ``` + +其中:**EPIPE** 是 socket send 函数可能返回的错误码之一。如果发送数据的话会在 Client 端触发 RST(指Client端的 FIN_WAIT_2 状态超时后连接已经销毁的情况),导致send操作返回 `EPIPE`(errno 32)错误,并触发 `SIGPIPE` 信号(默认行为是 **Terminate**)。 + +> What happens if the client ignores the error return from readline and writes more data to the server? This can happen, for example, if the client needs to perform two writes to the server before reading anything back, with the first write eliciting the RST. +> +> The rule that applies is: When a process writes to a socket that has received an RST, the SIGPIPE signal is sent to the process. The default action of this signal is to terminate the process, so the process must catch the signal to avoid being involuntarily terminated. +> +> If the process either catches the signal and returns from the signal handler, or ignores the signal, the write operation returns EPIPE. + +UNP(unix network program) 建议应用根据需要处理 `SIGPIPE`信号,至少不要用系统缺省的处理方式处理这个信号,系统缺省的处理方式是退出进程,这样你的应用就很难查处处理进程为什么退出。对 UNP 感兴趣的可以查看:http://www.unpbook.com/unpv13e.tar.gz。 + +下面是2个苹果官方文档,描述了 socket 和 SIGPIPE 信号,以及最佳实践: + +[Avoiding Common Networking Mistakes](https://developer.apple.com/library/archive/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/CommonPitfalls/CommonPitfalls.html) + +[Using Sockets and Socket Streams](https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/NetworkingTopics/Articles/UsingSocketsandSocketStreams.html) + + + +### 2. ... + diff --git a/assets/2021-04-06-NetworkFatalError2.png b/assets/2021-04-06-NetworkFatalError2.png new file mode 100644 index 0000000..d2d6aec Binary files /dev/null and b/assets/2021-04-06-NetworkFatalError2.png differ diff --git a/assets/2021-04-06-NetworkFatlError.png b/assets/2021-04-06-NetworkFatlError.png new file mode 100644 index 0000000..be05a65 Binary files /dev/null and b/assets/2021-04-06-NetworkFatlError.png differ