GithubHelp home page GithubHelp logo

异步服务有些问题. about gotcp HOT 18 CLOSED

gansidui avatar gansidui commented on July 22, 2024
异步服务有些问题.

from gotcp.

Comments (18)

gansidui avatar gansidui commented on July 22, 2024

消息只发一部分就断开连接,这个在生产环境中是很正常的,需要客户端和服务器做异常处理(以及心跳包),这是避免不了的。

from gotcp.

ronalfei avatar ronalfei commented on July 22, 2024

不太同意,因为这个异常是服务缺陷导致的,并非正常情况,同样条件下如果单goroutine处理连接部分就不会产生这些异常。

发自我的 iPhone

在 2015年11月11日,22:01,Jie Li [email protected] 写道:

消息只发一部分就断开连接,这个在生产环境中是很正常的,需要客户端和服务器做异常处理(以及心跳包),这是避免不了的。


Reply to this email directly or view it on GitHub.

from gotcp.

gansidui avatar gansidui commented on July 22, 2024

单个goroutine不是一样有这个问题么,在write数据的时候,服务器进程都结束了,还能够保证服务不中断(或者缺陷)?

from gotcp.

ronalfei avatar ronalfei commented on July 22, 2024

不是服务器进程结束,而是三个gorout间有影响,单gort,在处理上是顺序的,所以不会有影响,三个gort的影响在于从chan读数据,遇到eof并不表示客户端退出或即将退出,因为这时候很有可能还在接受write gort的数据。

发自我的 iPhone

在 2015年11月11日,23:30,Jie Li [email protected] 写道:

单个goroutine不是一样有这个问题么,在write数据的时候,服务器进程都结束了,还能够保证服务不中断(或者缺陷)?


Reply to this email directly or view it on GitHub.

from gotcp.

gansidui avatar gansidui commented on July 22, 2024

可是目前这3个goroutine只有当 exitChan (和 conn)关闭时才会返回啊, https://github.com/gansidui/gotcp/blob/master/conn.go#L141 不知道你前面描述的是不是这个意思?

from gotcp.

ronalfei avatar ronalfei commented on July 22, 2024

嗯, 基本就是这个意思. 这个错误是客户端频繁报connectionresetbypeer, 我才跟到select这里的.
exitchan和closechan都是特定促发的, 那这个问题应该是接口函数引起的了.
如果readpacket这个接口函数读出来是eof,
https://github.com/gansidui/gotcp/blob/master/conn.go#L150
https://github.com/gansidui/gotcp/blob/master/examples/telnet/telnetProtocol.go#L53
这时候这个goroutine就退出了, 退出导致了c.lose()执行了 conn.close()
https://github.com/gansidui/gotcp/blob/master/conn.go#L150

如果这时候write goroutine还在传输数据给客户端, 是不是会导致客户端报出resetbypeer?
我不是很清楚conn.close()是不是强制关闭tcp连接.

from gotcp.

gansidui avatar gansidui commented on July 22, 2024

没错, conn.close() 就是关闭连接(当然这中间的四次挥手细节没必要关注)。
readpacket接口是使用者自定义的,如果返回了error,在上一层(readloop)当然会认为这个连接出现了错误,那就应该关闭连接。
你提到的返回EOF,应该是conn关闭了导致的。

from gotcp.

ronalfei avatar ronalfei commented on July 22, 2024

如果readpacket出错, 导致connection被强制关闭, 而write还在写数据, 这种情况下, 服务端是否需要保证这次数据发送成功呢? 我觉得需要保证一下, 当共用连接(或者一个连接发送多次请求)的时候, 很有可能由于第二个请求包的某些问题影响了第一次的响应发送.
连接的处理我觉得不应该会受应用逻辑的影响, 应该还是server层管理会比较好.

from gotcp.

gansidui avatar gansidui commented on July 22, 2024

你认为readpacket出错了,还能保证正常write数据过去么?
readpacket出错基本就是socket io错误了(更多情况是socket已经关闭),这种情况下当然最好是去关闭它,而不是继续write。
这是我的看法

from gotcp.

ronalfei avatar ronalfei commented on July 22, 2024

write的数据是第一次的结果,而不是第二次的.

发自我的 iPhone

在 2015年11月12日,19:05,Jie Li [email protected] 写道:

你认为readpacket出错了,还能保证正常write数据过去么?
readpacket出错基本就是socket io错误了(更多情况是socket已经关闭),这种情况下当然最好是去关闭它,而不是继续write。
这是我的看法


Reply to this email directly or view it on GitHub.

from gotcp.

gansidui avatar gansidui commented on July 22, 2024

我知道你是write前面一次请求的结果,但是既然发生了socket io错误,那么socket就已经关闭了,与server端是否调用conn.close()没关系。
对于这种情况只能是在client端做缓存,如果请求没有收到ACK, 那么超时后应该重发请求。

from gotcp.

ronalfei avatar ronalfei commented on July 22, 2024

客户端出错处理当然是必须的. 因此才会知道服务器在处理的时候出了一些问题. 因此我一路跟下来到这里,能确定是三个goroutine之间的关系导致一些问题产生, 具体如何产生的, 暂且先不讨论了, 毕竟这个地方我没有在跟踪下去了, 因为自己压测却不能模拟出真实的环境.
我在实际环境中看到了两个问题. 第一个是这个issue描述的问题, php客户端会频繁报connectionresetbypeer.
第二个是内存使用, 在一段时间之后达到了7.5G, 而第一个版本的代码只占了63M.
后来我优化了很久的代码, 把很多struct都采用buffer的机制缓冲了起来, 也改了一些应用逻辑的bug, 但是内存依然很大. 后来通过go tool观察了内存使用, 发现newConn会比较占内存, 这个地方不知道如何优化, 而且客户端报错的问题也没解决掉.因此我把tcpserver这部分重写了, 一个连接配一个goroutine处理(应用逻辑也是这个goroutine处理). 其余代码没做修改.
现在的版本内存占用只有10M, php客户端也没有报出问题了.

from gotcp.

ronalfei avatar ronalfei commented on July 22, 2024

我觉得三个goroutine都能控制一个connection就和三个进程共享一块内存一样. 如果不采用锁的机制, 那就排队进行. 否则肯定会出异常.

from gotcp.

gansidui avatar gansidui commented on July 22, 2024

socket是可以同时读和写的,而在handleLoop并没有直接读写socket,所以不需要加锁。
如果只用一个goroutine去处理client的话有一定局限,比如:message push

你说内存一直没有释放的问题是由newConn导致的,这个我再仔细测试一下。

这个issue先别关吧

from gotcp.

larryli avatar larryli commented on July 22, 2024

@ronalfei net.Conn 是可以同时读写的,也就是全双工。实际上也可以多个 goroutine 同时读写(golang 内部锁机制),但是由于 socket 包没有边界,并发读是无法控制能读到什么,但是并发写是没有问题(当然,只能一次性写,不能拆包写)。

from gotcp.

simon8410 avatar simon8410 commented on July 22, 2024

内存泄漏的结果如何呢?这么长时间过去了 @gansidui

from gotcp.

gansidui avatar gansidui commented on July 22, 2024

@simon8410 测试过demo,暂未发现内存泄露. go是带垃圾回收的,如果发现内存居高不下,可能原因大概是两个:(1)本身数据耗内存,go不会将内存归还给操作系统,而是自己缓存起来 (2)存在数据循环引用导致内存泄露.

from gotcp.

ramilexe avatar ramilexe commented on July 22, 2024

guys, please write in english.

from gotcp.

Related Issues (16)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.