字节RPC框架kitex源码阅读(一)

Note 基于kitex@v0.11.3 开篇 随着分布式系统的发展,RPC(Remote Procedure Call,远程过程调用)已成为微服务架构中不可或缺的基础组件。RPC 通过让服务之间像调用本地方法一样发起远程调用,极大简化了跨进程、跨服务器的通信复杂度。对于开发者来说,选择一个性能稳定、易于使用的 RPC 框架至关重要。 ...

十月 22, 2024 · by NOSAE

clash规则配置

我一直在用的wmsxwd抑或是一元机场,这些厂商自带的代理规则都太少,对于没匹配上规则的网站,只能要么全部走代理或者全部直连,搞得我经常要手动切换。所以我需要一个相对更加全面的规则列表,让该走代理的网站走代理,该直连的直连!!! 无意中翻到clash-rules这个每日更新代理规则的仓库,便拿来用之。 使用方式如下: 去机场厂商那里拿到订阅链接,注意有的厂商不会直接给订阅链接而是托管链接,并且会给你一个网站自己去转换成订阅链接 创建一个.yaml文件(文件名随便),不同的客户端可能配置文件位置不同,比如我是放在~/.config/clash目录下 编辑文件内容,其中一些配置用原来默认的就行,比如我的是 mixed-port: 7890 allow-lan: true bind-address: '*' mode: rule log-level: info external-controller: '127.0.0.1:9090' 配置proxy-providers配置,顾名思义,配置代理 proxy-providers: CNIX: # 代理名称,自定义即可 type: http # 以远程下载的方式获取代理 url: "订阅链接" # 填写你的订阅链接 path: ./cnix.yaml # 从订阅链接下载存到本地的cnix.yaml文件 interval: 86400 # 更新间隔(s) 配置rule-providers,顾名思义,配置代理规则,同样以远程的方式获取,并定时更新,参考仓库的教程即可,比如加入一个名为google的远程规则(不知道为什么jsdelivr我经常访问不了,所以就直接不走这个cdn了): rule-providers: google: type: http behavior: domain url: "https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/google.txt" path: ./ruleset/google.yaml interval: 86400 配置proxy-groups,CNIX就是刚刚配置的proxy-providers,这里定义一个代理组去使用它 proxy-groups: - name: PROXY type: select use: - CNIX 配置rules,将规则和代理组关联起来。除了PROXY以外,DIRECT和REJECT可视为默认的代理组,即直连和拒绝,其中拒绝网站通过查看reject.txt就能看到,包含一些广告网站或者人家的内部网站、垃圾网站等。想访问某个网站一直被拒而关掉clash后又能访问的话,可以看看是不是reject.txt的锅 ...

十月 21, 2024 · by NOSAE

k8s服务发现

基础知识 了解服务发现之前,先明确k8s内部为什么需要服务发现,而在了解为什么需要服务发现之前,先看下pod、service他们的关系。 应用运行在k8s的容器之中,而容器运行在pod内,一般来说一个pod一个容器 每个pod都处于一个扁平的IP网段内,每个pod都有其唯一IP,在这个网段内pod之间可以直接进行通信 在这个网络内,会新增、删除pod,从而也会分配新的IP或者删除IP,对于我们在pod内的应用来说,就得手动维护一个应用的IP列表,以此知道我们要访问别的应用时,对应的是哪个IP,非常耦合以及痛苦。 好在k8s提供了service这个组件,从网络的层面上,一个service代表了一组pod。当需要访问pod内的应用时,访问service的ip即可,而service除非手动删除变更,否则他的ip是稳定的。因此外界从直接访问ip经常变化的pod,变成了访问ip稳定的service,再由service将流量负载均衡到这些pod上。 服务发现是什么 平时用浏览器上过网都知道,输入一个网址比如google.com就能访问内容,背后是DNS帮我们将google.com解析成IP地址,最终浏览器才能基于TCP协议,从本地连接到这个服务提供商的IP地址。所以DNS属于服务发现的其中一种方式。 对于k8s内部来说,如果一个service中的pod的应用,想访问处于另一个service中pod的应用,最简单的就是知道对方service的IP地址。但我们编写应用的时候往往更希望连接的是一个service的名字而不是service的IP,因为service的IP说到底也还是动态分配的,如果service经过销毁重建,IP变化了,应用代码也得跟着改。 因此k8s需要服务发现,将service的名字解析为service的IP供应用去正确访问。 服务发现实际上包含两个功能点: 服务注册 服务发现 服务注册 k8s使用的是DNS服务发现,每个k8s集群都会在kube-system命名空间中运行DNS服务(这个服务本质上也是pod内的应用),称为集群DNS。每个service都会自动注册到集群DNS中,注册过程如下: 向API server提交一个新的service定义请求,请求经过认证、鉴权等准入策略后放行 Service分配得到ClusterIP,保存到集群数据仓库 在集群范围内传播该Service配置 集群DNS感知到该Service创建,创建DNS A记录 可以看到最关键的是第4步,这一步创建了A记录指向ClusterIP,这个A记录名称就是service的metadata.name,并且之后会持续关注这个Service对象。 接着就是service管理的pods,k8s自动为每个service创建endpoints对象,其中保存的是匹配标签选择器的pod列表,service后续会将流量负载均衡到这些pod上。 服务发现 为了让应用使用上集群DNS提供的服务发现功能,每个pod中的每个容器的/etc/resolv.conf文件都被配置为使用集群DNS进行解析。 比如图中my-app中的应用想要访问your-app中的应用,就得拿着"your-app-svr"这个名称去查询DNS服务拿到IP 10.0.0.20,但显然容器的网关并不维护到这个IP的路由,最终会缺省地转发到pod所在节点的网卡上,随后转发到节点的缺省网关,经过节点内核。 在继续之前,有必要插播一下:k8s的每个节点上都会运行一个名为kube-proxy的服务,其会监控API Server上service的变化,这些变化包括endpoints的变化(对应pod的增删),并根据这些变化创建iptables或IPVS规则,目的是告知节点捕获目标为Service的网络报文并转发给pod。 因此my-app发送出来的这个报文,最终会到达节点的缺省网关,经过节点内核时根据kube-proxy写入的路由规则,报文的目标IP被改成目标pod的IP。 参考 浅谈 Kubernetes 中的服务发现

十月 20, 2024 · by NOSAE

go GC

基础知识 Tip go的垃圾回收是没有分代,不整理,并发的三色标记清扫算法 go1.3标记清除 从gc root出发,标记所有可达对象。最后扫描整个head,将没有标记的对象(不可达对象)清除。但缺点是STW、需要扫描整个heap、清除后会产生大量碎片。 为了缓解STW来带的停止长时间用户程序执行,标记之后马上停止STW,清除阶段与用户程序并行执行。 ...

九月 25, 2024 · by NOSAE

golang GMP调度器

Note 本文基于go1.21.2,不同版本的go可能会有差异。文中部分代码会由于不是知识点强相关而省略,但被忽略的每行代码或多或少都有它们实际的用处,甚至可能不宜删除,欢迎指出 Tip 分析底层的相关的代码时,往往会由于平台架构而带来代码上的差异,比如我机器是darwin/arm64,使用vscode查看代码,而且我希望基于linux/amd64来看代码,可以在.vscode/settings.json中设置GOOS和GOARCH: ...

九月 24, 2024 · by NOSAE