V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  lesismal  ›  全部回复第 36 页 / 共 60 页
回复总数  1195
1 ... 32  33  34  35  36  37  38  39  40  41 ... 60  
2022-05-08 22:57:16 +08:00
回复了 ojh 创建的主题 程序员 关于 Java 笨重一说
@abcbuzhiming
比如农村里上茅草坑习惯了,后来进城里发现有智能马桶,很是高大上。
GraalVM 就相当于智能马桶。但即便智能马桶,它也还是屎屎相关。

go 可能像是在餐厅里吃饭,餐厅也是修得晚、软装还没完善,经常让小白们感觉斯是陋室,但这里的东西都是可以下咽的。
2022-05-03 10:40:16 +08:00
回复了 lesismal 创建的主题 分享发现 筑·格瓦拉
@hellodiu 感谢关注和使用 nbio !问题不多的话交流就可用了,不用付费。如果有周期稍微长点的项目需要顾问或者开发可用付费合作。
稍等我在 gmail 回复,或者你来 nbio 里开个 issue 也可用的,issue 的 markdown 比邮件更友好些。
2022-05-01 09:35:23 +08:00
回复了 lesismal 创建的主题 硬件 吃八分饱长寿与充电 85%能保护电池
各位还有什么类似的事情也列举下?
2022-04-28 10:06:10 +08:00
回复了 461da73c 创建的主题 Apple 用了多年 Mac,发现还是喜欢 Windows
楼主一人拥有 3mac+3win 而且都是好配置

炫耀帖,鉴定完毕
2022-04-25 21:51:30 +08:00
回复了 Vibra 创建的主题 程序员 [求助]如何查看一个动态库被多少进程所使用
遍历下 /proc 下所有进程的 /pid/maps ,grep 每个进程的内存空间看看哪些打开了这个 so ,细节楼主自己完善下:

find ./ -type d -maxdepth 1 | awk '{if(substr($0,3) ~ /^[0-9]+$/) print $0"/maps";}' | awk '{if(-f $0) print $0}'| xargs grep "your absolute path of .so" | awk '{split($0,a,"/"); print a[2]}' | uniq | awk '{if($0 ~/^[0-9]+$/) print "./"$0"/exe"}' | xargs ls -l | awk '{split($0,a," "); print a[11]}'
2022-04-25 12:11:39 +08:00
回复了 yanhomlin 创建的主题 程序员 开个主题讨论下线程池参数自适应调整的可能性
我们一些服务用 go 替换 java 后,内存消耗普遍降低了 50+%、个别服务占用降低 70%,cpu 消耗降低了 30-70%不等
2022-04-25 12:09:29 +08:00
回复了 yanhomlin 创建的主题 程序员 开个主题讨论下线程池参数自适应调整的可能性
楼主上一个帖子我忍住了没好意思说,这个帖子还是说下吧:

何不用 go?
2022-04-22 23:13:56 +08:00
回复了 learnjavamyself 创建的主题 新手求助 转行 pytho 求建议
大龄转,建议 devops 吧
python 本身工资一般、业务相关的项目经验积累更不容易,所以半路转、加上年龄因素会持续劣势。
devops 更偏向于工具、自动化开发技能本身、对业务相关的项目和框架经验要求不高,而且 devops 工资不错,以后想润的话国外也很火并且国外 devops 薪资似乎已经高于普通开发了
2022-04-22 23:10:32 +08:00
回复了 irisdev 创建的主题 程序员 有多少程序员真的在 996
真正 996 的人里,不会有太多人有时间来参加这个统计,所以你的统计结果会象是那架残破的飞机一样。
2022-04-22 23:08:03 +08:00
回复了 suueyoung 创建的主题 Go 编程语言 请问, 在 Golang 里面如何实现以下的 SQL?
注意注释地方:

```golang
package main

import (
"database/sql"
"log"

_ "github.com/go-sql-driver/mysql"
)

func main() {
// 默认不支持 multi statements ,要设置 multiStatements=true ,否则无法在一个 Exec/Query 里执行多条语句
db, err := sql.Open("mysql", "root:123qwe@tcp(127.0.0.1:3306)/?charset=utf8mb4&multiStatements=true")
if err != nil {
log.Fatal(err)
}

result, err := db.Query(`
SET SESSION block_encryption_mode = 'aes-256-ecb';

SELECT filed
FROM schema.table
WHERE encrypted_field in (
SELECT HEX(AES_ENCRYPT('123', 'secret'))
);
`)
if err != nil {
log.Fatal(err)
}

defer result.Close()
for result.Next() {
var filed string
err = result.Scan(&filed)
if err != nil {
log.Fatal(err)
}
log.Println("filed:", filed)
}
}
```
2022-04-21 21:45:59 +08:00
回复了 henryisme 创建的主题 程序员 2022 年了,目前的 go web 框架 Gin Beego Iris 如何选择?
有一些号称微服务的框架挺火的,但其实微服务哪有什么框架,就是一些基础组件稍微封装下罢了,很多基础组件又是封装下别人的库、自己另外起个名字、然后就号称自己实现了一套 xxx 了

这些项目都是脚手架类型,更大程度上是一种工程模板,称作框架都有点高抬了
2022-04-21 21:41:10 +08:00
回复了 henryisme 创建的主题 程序员 2022 年了,目前的 go web 框架 Gin Beego Iris 如何选择?
@haha512 #43 也不全是因为政治正确,因为确实很多国人项目 KPI 导向、污染了环境,也不能全怪国人作者,因为一些厂就有这些 KPI 指标,跟内卷是一个道理,都是资本家逼的

@securityCoding #47 有一些知名的项目臭大街的程度也比较高、已经有无数人喷过了,所以也并不都是装逼而喷,得就事论事
2022-04-21 21:35:38 +08:00
回复了 henryisme 创建的主题 程序员 2022 年了,目前的 go web 框架 Gin Beego Iris 如何选择?
可以试试我这个,rpc 框架一把梭,request 、推送、广播,随便弄:

websocket:
github.com/lesismal/arpc/tree/master/examples/webchat

websocket+http:
github.com/lesismal/arpc/tree/master/examples/httprpc
2022-04-19 19:39:58 +08:00
回复了 denua1 创建的主题 Go 编程语言 GlideIM - Golang 实现的高性能的分布式 IM
gorilla/websocket 或者其他基于标准库 net.Conn 的,一个连接 1-3 协程,面对海量连接数都吃力,可以试试我的:
github.com/lesismal/nbio

rpc ,我也写了个,性能更强一些、内存占用更少,扩展性、支持的功能更丰富甚至可以直接用于 IM 的通讯。但是服务之间 rpc 的连接数一般不大,所以用哪个也都还好,只是其他的框架 qps/tps 要差一些,如果有兴趣可以试下我的:
github.com/lesismal/arpc
benchmark 可以参考这些,最好是自己亲自跑、别直接参考库作者自己给出的结果:
github.com/micro-svc/go-rpc-framework-benchmark
github.com/rpcxio/rpcx-benchmark
github.com/cloudwego/kitex-benchmark
2022-04-19 11:15:44 +08:00
回复了 v2410117 创建的主题 随想 有多少人接受了自己平庸的?
摆脱平庸不是什么难事,不是非要做出很大的成就才算不平庸。
多点思考,或者随便什么方向的知识、喜好,往深入了研究研究,就能让自己对某项事物的认识达到某种高度,而万事万物背后的大道理都是相通的,思想境界到了,就不平庸了。

经济学第一定律是稀缺性,所以不能所有人都达到很大的成就,不管多么努力,绝大多数人都注定平凡。
人可以平凡,但不必平庸。

看透了躺平了接受了自己的平凡,这也是一种认知提升,生活变好了,楼主现在八成已经不是个平庸的人了呢。
2022-04-18 10:38:36 +08:00
回复了 gantleman 创建的主题 游戏开发 为什么 luacluster 可以实现万人同屏?
做技术的不踏踏实实,半吊子老来故弄玄虚地吹是真烦
2022-04-03 23:01:58 +08:00
回复了 josexy 创建的主题 Go 编程语言 Go 的网络轮询器疑惑?
我不敢说这就是原因,只作为猜测:
1. pipe 和 event 都可以实现功能
2. pipe 每次只需要 write 1 字节,而 eventfd 每次必须写入大于等于 8 字节、相比之下浪费
2022-04-01 00:49:06 +08:00
回复了 notokoy 创建的主题 Go 编程语言 Go 流媒体(直播音视频)服务器 LAL - 开源自荐
@notokoy

哦对了,slack 跟用英语没什么关系。我不用微信之类的是因为被一些事情恶心到了,所以跑到 slack 上躲清静。一些国人知名开源项目也在 slack 上开频道了,而且 slack 、discord 这些有现成的 github 相关的 app/功能集成,做自己开源项目还是有些便利的
2022-03-31 23:51:50 +08:00
回复了 notokoy 创建的主题 Go 编程语言 Go 流媒体(直播音视频)服务器 LAL - 开源自荐
@notokoy #19

哥们太客气了,我也能从你的项目中学到不少流媒体的知识,交流下来,大家都有收获就很开心。

> 不过。我依然觉得即使基于性能考虑,在流媒体场景也不是十分必须。

对,所以我一直说的是海量并发场景的问题。我前面和接下来说的也是基于海量并发,普通并发量,标准库绝对足够了。
按照普通硬件配置比如 4c8c ,1-5w 这种连接数,poller 的相应性能没有优势,甚至因为异步流编解码更复杂而不如标准库响应性能好,而内存的节约也是对应交互频率等存在一定的阈值,阈值范围内,标准库更优

> 第一,现在一条直播流的带宽随随便便就超过 Mb 了,以后的趋势应该是越来越大。即使是 CDN 应用,受限于带宽,连接也不会太多吧。
> 真要是单个节点那么大的量,我觉得可以考虑多进程了。

这倒是不一定,多网卡多线,还有不同码率的包 size 未必真就是单节点不会太高连接数。而且单进程的 go 的 net.Conn 如果有瓶颈,改成单硬件上的多进程仍然高成本,只能加硬件,这个倒不是能不能搞定业务的问题,主要是硬件成本、部署节点数量维护成本之类的

> 第二,流媒体场景,还有一点和很多短连接场景不同,就是连接间有很多交互,比如数据转发。

这个确实是,但不管是 net.Conn 、poller 方案,还是 c/cpp 也都有同样的成本。所以这一点上成本的区别不大,无非就是 map 上再加点 buckets 之类的来降低锁的粒度来减少竞争成本。
所以主要的区别仍然是协程数量导致的内存、gc 、调度的压力

> 我看过一些 IO 框架。
> 基本实现是支持多个 event loop ,然后连接绑定到一个固定的 event loop 中。

对于读,姿势有点多,常见的一些用法:
1. LT 模式如果跨协程 /线程去处理 event ,则可能会有事件的多次重复派发导致事件和事件对应的读 syscall 浪费(也可以做标记避免一些重复读的浪费,但事件的重复派发也是内核和应用层的浪费),所以这种基本上是在 epoll 协程 /线程里直接进行
2. ET 模式,可以像 LT 那样直接在 epoll 循环里读,也可以把事件传给专门的 IO 协程 /线程去处理读,因为 ET 是每次有新的数据只会触发一次、不像 LT 那样只要未读完就不停触发,加上协议交互、窗口拥塞机制,所以即使跨协程 /线程处理读、ET 也不会有太多事件的重复派发,但需要注意每个 conn 的读应在确定的协程 /线程中进行,否则多个并发流读的时候可能造成数据顺序的混乱
3. ET+ONESHOT ,可以避免事件重复派发,可以让协程 /线程池中的每个任务比较均衡地获取事件进行处理,不至于像 ET 那样跨并发流传递必须注意单个 conn 的有序读;但是 ONESHOT 因为每次需要重复添加事件,如果每种使用方式实现比较良好的情况下,则 ONESHOT 方式下整体上浪费更多的 epoll syscall ,所以通常性能比 LT 或 ET 的吞吐要差一些

我自己框架中可配置 LT 或者 ET 、不支持 ET+ONESHOT ,因为实测 LT 吞吐要略好所以默认配置是 LT 。另外就是 IO 通常也不会是一个服务的全部 cpu 消耗,所以即使是丢个这几个 IO 协程 /线程,交给系统去自然调度也是能够达到整体均衡的。

对于写,也基本是 conn 直接写的多一些,缓冲区满、写失败了才会把写事件加到 event 里然后等待可写再 flush 。

> 一些性能测试,是在自身 event loop 中 echo 数据,这种场景有两个特点:
> 1. 没有涉及到跨协程交互,可以无锁。
> 2. 理论上,一个 event loop 的所有连接可以共用一块读内存,因为不会长久持有。

如果是针对流媒体服务这种涉及不同连接之间的交互的,你举例子的这里的无锁有两个条件:
1. 只有一个 event loop
2. 所有 IO 、逻辑也都是在这个 event loop 中

如果不满足这两个条件,收到一个连接的数据想推送给另一个,就仍然需要锁,而满足这两个条件付出的代价可比锁大多了:
1. 只能利用单核
2 go 的指令速度还是不够快
3. 虽然是非阻塞,但涉及 IO 毕竟也是 syscall 、不是纯 cpu 消耗,所以仍然是慢

另外关于内存,其实这种场景的内存优化,普通连接数的时候,一不小心甚至比标准库更耗内存,主要区别是:
1. net.Conn 方案是读一个 message 处理一个然后下一个、同一个 buffer 可以复用
2. poller 框架节省协程数量,但是要想不被单个连接线头阻塞、IO 协程读到完整消息后需要丢给不同的协程去处理逻辑,同一个 conn 同时可能几个 message 在等待处理,而且这些 buffer 是跨协程的、生命周期更复杂,没法像标准库方案那样方便复用

结论就是各种消耗,标准方案主要与在线量相关,poller 方案主要与交互频率相关,所以前面提到阈值,不同的在线量、交互频率下,二者各有不同的优劣表现。

我最初也是写 c/cpp 的框架,写 go 的这个发现 go 比 c/cpp 的框架甚至还要复杂些,因为默认带 gc ,使用 sync.Pool 也无法精准控制,需要做更多策略。而且 go 的指令不够强,如果像很多 c/cpp 框架那样做成逻辑单线程则性能不够,所以 go 仍然需要逻辑多协程,而这又涉及到更多的锁、时序、一致性相关的细节优化,所以除了语法简单了,实现姿势其实有更多改变


PS: 最后再重复下,标准库方案绝大多数时候够用了,咱们探讨的 poller 只针对海量并发这种,所以我不是一定要劝楼主搞异步框架,够用就好:joy:
2022-03-31 18:46:47 +08:00
回复了 notokoy 创建的主题 Go 编程语言 Go 流媒体(直播音视频)服务器 LAL - 开源自荐
@notokoy #34

微信太闹腾了浪费很多时间,而且歪果仁也基本不用,你有 slack 频道没?可以 slack 弄点频道、还能进军海外扩张一下。也欢迎来我的项目的频道:
https://arpcnbio.slack.com/join/shared_invite/zt-16e6yu1mb-FUsil~2Jmn4Usl~IX_zv3g#/shared-invite/email

多数内部业务、尤其是需要很多功能定制的流媒体服务确实不需要太大在线量,毕竟外面有云、CDN 网络层层分担了在线数量的压力、同一 topic 只需要针对外层基础设施请求回源的节点数量就够用了,这个数量不会太大,而这些基础设施可能主流仍然是 c/cpp 的。
如果用 go 做云、CDN 之类的基础设施的开发、面向用户量很大,net.Conn 的开销也确实是还对应着挺高的硬件成本的,如果能换成 poller 和更多的内存优化,还是能声调不少资金、对能源环境问题也友好。

QUIC 这种也是路漫漫,不知道啥时候能普及,我的 poller 库只支持了 TLS/HTTP1.x/Websocket ,不打算支持 HTTP2.0 因为 2.0 太渣了。目前 go 的 QUIC 实现,也同样是一个连接至少一个协程,海量并发照样也是消耗很多资源。但是因为基于 UDP ,而 go 的 UDP 标准库已经足够简单了,所以我的 poller 库不打算支持 UDP 。至于 QUIC ,以后如果有档期,我也想搞一份不需要每个连接至少一个协程的实现,kcp-go 之类的类似标准库方案的一连接一协程也是同样的对海量并发不友好,海量并发时开销远超过其他语言的性能比较好的异步框架,剩下的只剩同步逻辑的便利,性能和消耗比其他语言异步框架劣势很多、甚至在基础设施领域,同步的便利已经无法弥补这个消耗的成本损失了。
每一样基础设施的工作量都有点大,真是想做很多但时间不够用了:joy:

你说的 go 的 io 线程数量应该是指 poller 线程数,这里先以这个作为前提,否则这样说可能不太准确。
之前我也没注意过 go 的 poller 线程数量是否只有 1 个,刚写代码试了下,net.Listen 0 个到 100 地址的时候,以及连接数 0 到 20w 的不同组合,确实都只有一个 eventfd ,而且即使不 listen 、没有连接也会有 eventfd ,是处理所有类型 fd 的 nonbloking 的:
但 top -Hp 查看,随着 net.Listen 地址数量或者连接数的增加,这 listener 和连接数的增加都对应着线程数的增加,应该是协程数多或者所需资源多时,runtime 动态增加了所需的线程。
考虑到 epoll 的不同用法和线程数量的情况,猜测 golang et 模式、epoll 线程里只是处理事件而不进行实际的读写,事件与 runtime 调度结合去触发用户协程的可读写唤醒,实际的读写则发生在用户的协程里,对应的是整个 runtime 的线程池 MPG 调度时被执行,而这个线程也是前面提到的随着负载增加而由 runtime 去增加的。所以前面我觉得“go 的 io 线程数量只有 1 个”这个说法可能不太准确。

引入 IO 框架倒还好,只是如果支持异步 IO ,编解码器要像 c/cpp 那样实现的是异步流解析,不像使用 net.Conn 同步解析这么简单,需要定制优化的地方也更多。统一实现成异步的编解码后,编解码器只收数据进行解析就可以、其实也就无所谓 IO 层是同步还是异步了,我的框架里目前就是这样,uni*是 epoll/kqueue 异步、windows 是使用 net.Conn 封装了下,框架传递数据给应用层。
并且,IO 这层节省了大量的协程数量,应用层则仍可以使用有限数量的协程池,而且应用层的协程池 1w-10w 这种 size 级别也足够用了,有特殊的阻塞需求还可以定制不同的 pool 来控制整个系统的协程资源,这样我们仍然可以在应用层写同步逻辑,我的库里现在就是这样做的,跑着效果还算挺好
1 ... 32  33  34  35  36  37  38  39  40  41 ... 60  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2666 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 40ms · UTC 15:47 · PVG 23:47 · LAX 07:47 · JFK 10:47
Developed with CodeLauncher
♥ Do have faith in what you're doing.