作者回复: 你要明白一件事儿,客户端发来一条数据,直到服务端返回给客户端发送成功,这段时间内,数据是允许丢失的。
数据丢失后,客户端收不到发送成功响应,自然会重试。
作者回复: 👍👍👍
作者回复: 这个流程中处理的数据已经是被分配过的,单个队列的数据。
作者回复: 不会丢,因为数据已经复制到了从节点上,leader宕机后,会重新选举出新的leader(也就是之前的某个follower),这个新leader上是有原leader上的全部数据的。
作者回复: 一般简单常用的做法都是在处理request的线程中执行业务逻辑,然后把response返回。
其实从网络层面来看,Request和Response只是客户端和服务端互相发送的两段数据,和服务端处理用什么线程完全没有关系。
Request和Response如何对应,这个取决于网络传输协议是怎么设计的。这个我们在课程中讲过。
在服务端实现中,可以接受到Request之后,进行异步处理,异步处理完成之后,无论在什么线程中,只要能拿到处理结果构建出Response,通过网络发给客户端就可以了。
作者回复: 👍👍👍
作者回复: 👍👍👍正确写出这个程序差不多就是这个耗时。
作者回复: 还是贴一下GitHub的链接把,也方便其他同学学习。
作者回复: 这个地方是因为,完成了所有会话之后,关闭socket连接的时候,没有先等待2个大爷读写socket的4个线程都结束导致的。
虽然不影响结果,但还是可以改进一下,做到优雅的退出。
作者回复: 你的大部分理解都没问题,有一个小问题是,维持一个TCP连接并不一定需要占用一个线程。只有在这个连接上执行收发数据的时候,才需要占用线程。收到请求处理完,把请求交给其它线程处理后,当前线程就可以释放了。直到响应生成后,这段时间只维持TCP连接是不需要占用任何线程的。
作者回复: 不是这样的,以你这个例子来说,假设abcd这条消息前面再也没有其它消息的,它是最前的一条,abcd这条消息的offset就是0, abcdefgh这条消息的offset就是6.
作者回复: 后续我们会把所有代码都开源出来的。
作者回复: 是的,这里的“异步”是指,发响应给客户端并不是由复制或者刷盘线程来执行的,而是单独的一组线程。给每个客户端发响应这个操作是可以并行执行的。
作者回复: 👍👍👍
最好能说一下你优化了哪些地方。