iproute2 > 路由表, routing table, ip route

iproute2 > 路由表, routing table, ip route commands ip route # 简写, Abbreviations # route: ro, r. # show: list, sh, ls, l. ip route ls tab all ip route Usage: ip route { list | flush } SELECTOR := 表示声明并定义 { xxx | xxx } 表示多选 - 必选 [] 表示可选 SPEC 应该是 specification 的缩写 NH 应该是 next hop 的缩写 PREFIX 就是地址加掩码的格式, 比如 0.0.0.0/0 PREFIX 有个 default 的特殊表示, 等同于 0.0.0.0/0, 也就是默认路由 路由表 linux 系统路由表可以自定义从 1-252 个路由表, 操作系统维护了 4 个路由表: ...

2022-02-11 · 14 min · 2819 words · -

tcpcopy, 流量复制

tcpcopy, 流量复制 公有云环境 https://github.com/session-replay-tools/tcpcopy/issues/336 云环境下,安全策略可能会干扰测试的进行 采用如下步骤可以规避麻烦: 测试机器和 intercept 部署到一台机器 tcpcopy端 -c 参数采用 tcpcopy 所在的线上机器ip地址 在线上机器设置iptables黑洞来过滤掉测试服务器的响应包 iptables -I INPUT -p tcp --sport 测试服务的端口 -j DROP -s 测试服务所在机器的ip地址 千万要注意在测试服务器不要设置路由了,否则会受到干扰 环境 测试用的 tcp 服务 tcp-echo-server 线上服务器, online source server, xxx.xxx.20.50 2000 端口提供服务 (tcp-echo-server) 测试服务器, 目标服务器, target server, xxx.xxx.20.45, 192.168.50.102 3000 端口提供服务 (tcp-echo-server), 不能跟 online server 用同一个端口 辅助服务器, assistant server, xxx.xxx.20.45, intercept 跟测试服务部署到同一个机器, 不使用单独的服务器 线上服务器安装 tcpcopy git clone https://github.com/session-replay-tools/tcpcopy.git cd tcpcopy ./configure --single make make install ls /usr/local/tcpcopy 辅助服务器 (intercept) 安装 git clone https://github.com/session-replay-tools/intercept.git cd intercept ./configure --single make make install ls /usr/local/intercept 实时复制流量 测试服务器 192.168.50.102 测试服务器不添加路由规则. ...

2022-02-11 · 3 min · 630 words · -

chrome command

chrome command # linux 启动浏览器并打开 URL google-chrome-beta gmail.com google-chrome-beta http://localhost:8080 https://stackoverflow.com/questions/28162697/how-can-i-open-google-chrome-from-the-terminal-with-the-url-localhost3000 Chrome 有很多的特性在界面菜单中是没有体现的,你可以通过 chrome:// 命令来访问。本文介绍 12 个非常有用的 chrome:// 命令: chrome://flags 可用来启用或者关闭某些 chrome 的体验特性 chrome://dns 该命令将显示浏览器预抓取的主机名列表 chrome://downloads 该命令同时也可以从菜单中的下载来访问,其快捷键是 Ctrl + J chrome://extensions 该命令等同于菜单 - 工具 - 扩展 chrome://bookmarks 改名了等同于菜单-书签-书签管理器,快捷键 Ctrl+Shift+O chrome://history 该命令可从菜单-历史直接访问,快捷键 Ctrl+H chrome://memory 该命令将重定向到 “chrome://memory-redirect/”. 它将显示浏览器使用内存的情况,以及系统中运行的其他浏览器,包括 firefox。同时还显示浏览器进程的详细信息。 chrome://net-internals 该命令显示网络相关信息,用来捕获浏览器生成的网络事件,可导出数据,可查看DNS主机解析缓存。 其中一个很重要的功能就是"测试",如果你无法访问某个网址,那么可以使用 “chrome://net-internals” -> 点击"Tests" tab -> 输入网址,并点击开始测试,Chrome 将报告具体的问题所在。 chrome://quota-internals 该命令用来显示浏览器所使用磁盘空间配额的情况。 chrome://sessions 该命令用来显示当前运行的浏览器的会话信息数以及详细列表 chrome://settings 该命令可通过菜单-选项直接访问,可用来控制浏览器各项设置值 chrome://sync-internals 用来显示 chrome 的同步状态 最后,如果你想查看 chrome 所有的命令,可使用 chrome://about/ ...

2022-01-22 · 1 min · 77 words · -

Cookie

Cookie Http Cookies 中 Max-age 和 Expires 有什么区别 快速回答 Expires 为 Cookie 的删除设置一个过期的日期 Max-age 设置一个 Cookie 将要过期的秒数 IE 浏览器(ie6、ie7 和 ie8) 不支持 max-age,所有的浏览器都支持 expires 深入一些来说明 expires 参数是当年网景公司推出 Cookies 原有的一部分。在 HTTP1.1 中,expires 被弃用并且被更加易用的 max-age 所替代。你只需说明这个 Cookie 能够存活多久就可以了,而不用像之前那样指定一个日期。设置二者中的一个,Cookie 会在它过期前一直保存,如果你一个都没有设置,这个 Cookie 将会一直存在直到你关闭浏览器,这种称之为 Session Cookie。 https://jiapan.me/2017/cookies-max-age-vs-expires/

2022-01-22 · 1 min · 42 words · -

RESTful API 设计

RESTful API 设计 URI中不应包含结尾的正斜杠(/)。 域名 应该尽量将API部署在专用域名之下。 https://api.example.com 如果确定API很简单,不会有进一步扩展,可以考虑放在主域名下。 https://example.org/api/ 版本 Versioning 应该将API的版本号放入URL。 https://api.example.com/v1/ 另一种做法是,将版本号放在HTTP头信息中,但不如放入URL方便和直观。Github采用这种做法。 路径 Endpoint 路径又称"终点" endpoint,表示API的具体网址。 在RESTful架构中,每个网址代表一种资源 resource,所以网址中不能有动词,只能有名词,而且所用的名词往往与数据库的表格名对应。一般来说,数据库中的表都是同种记录的"集合" collection,所以API 中的名词也应该使用复数。 HTTP动词 对于资源的具体操作类型,由HTTP动词表示。 常用的HTTP动词有下面五个 (括号里是对应的SQL命令)。 GET (SELECT):取出资源 (一项或多项)。 POST (CREATE):新建一个资源。 PUT (UPDATE):更新资源 (客户端提供改变后的完整资源), Replace (Create or Update) 如果存在就替换, 没有就新增. 在HTTP中,PUT被定义为幂等(idempotent)的方法,POST 则不是,这是一个很重要的区别 PATCH (UPDATE):更新资源 (客户端提供改变的属性)。 DELETE (DELETE):删除资源。 还有两个不常用的HTTP动词 HEAD:获取资源的元数据。 OPTIONS:获取信息,关于资源的哪些属性是客户端可以改变的。 状态码 (Status Codes) 服务器向用户返回的状态码和提示信息,常见的有以下一些 (方括号中是该状态码对应的HTTP动词)。 200 OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的 (Idempotent)。 201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。 202 Accepted - [*]:表示一个请求已经进入后台排队 (异步任务) 204 NO CONTENT - [DELETE]:用户删除数据成功。 400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的。 401 Unauthorized - [*]:表示用户没有权限 (令牌、用户名、密码错误),未登录或会话过期 (需要登录但未登录或会话过期) 403 Forbidden - [] 表示用户得到授权 (与401错误相对),但是访问是被禁止的。没有权限访问、操作 (IP受限或已登录但没权限) 404 NOT FOUND - []:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的。 406 Not Acceptable - [GET]:用户请求的格式不可得 (比如用户请求JSON格式,但是只有XML格式)。 410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。 422 Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。 500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。 RESTful API 设计指南 作者: 阮一峰 版权声明:自由转载-非商用-非衍生-保持署名 (创意共享3.0许可证) ...

2022-01-21 · 1 min · 188 words · -

无限层级留言

无限层级留言 mysql 邻接表 路径枚举 嵌套集 闭包表 redis https://www.phpbloger.com/article/50.html https://blog.bfw.wiki/user6/16249674164961840043.html

2022-01-18 · 1 min · 9 words · -

archlinux packages

archlinux packages aalib: ASCII art graphic library aardvark-dns: Authoritative dns server for A/AAAA container records adwaita-fonts 是一个包含 Adwaita 字体(Adwaita Fonts) 的软件包。提供了一套由 GNOME 项目开发的字体, wechat sudo abseil-cpp: Collection of C++ library code designed to augment the C++ standard librar ansible ansible-core aom: Alliance for Open Media video codec appstream: Provides a standard for creating app stores across distributions at-spi2-core: Protocol definitions and daemon for D-Bus at-spi audit: Userspace components of the audit framework ...

2021-12-30 · 2 min · 364 words · -

微服务注册中心

“微服务注册中心” 微服务注册中心, ZooKeeper, Eureka, Consul, Nacos 服务注册中心本质上是为了解耦服务提供者和服务消费者。对于任何一个微服务,原则上都应存在或者支持多个提供者,这是由微服务的分布式属性决定的。更进一步,为了支持弹性扩缩容特性,一个微服务的提供者的数量和分布往往是动态变化的,也是无法预先确定的。因此,原本在单体应用阶段常用的静态LB机制就不再适用了,需要引入额外的组件来管理微服务提供者的注册与发现,而这个组件就是服务注册中心。 CAP理论 CAP理论是分布式架构中重要理论 一致性(Consistency) (所有节点在同一时间具有相同的数据) 可用性(Availability) (保证每个请求不管成功或者失败都有响应) 分隔容忍(Partition tolerance) (系统中任意信息的丢失或失败不会影响系统的继续运作) P的理解,我觉得是在整个系统中某个部分,挂掉了,或者宕机了,并不影响整个系统的运作或者说使用, 而可用性是,某个系统的某个节点挂了,但是并不影响系统的接受或者发出请求,CAP 不可能都取,只能取其中2个 原因是 如果C是第一需求的话,那么会影响A的性能,因为要数据同步,不然请求结果会有差异,但是数据同步会消耗时间,期间可用性就会降低。 如果A是第一需求,那么只要有一个服务在,就能正常接受请求,但是对与返回结果变不能保证,原因是,在分布式部署的时候,数据一致的过程不可能想切线路那么快。 再如果,同事满足一致性和可用性,那么分区容错就很难保证了,也就是单点,也是分布式的基本核心,好了,明白这些理论,就可以在相应的场景选取服务注册与发现了 Zookeeper -> CP 与 Eureka 有所不同,Apache Zookeeper 在设计时就紧遵CP原则,即任何时候对 Zookeeper 的访问请求能得到一致的数据结果,同时系统对网络分割具备容错性,但是 Zookeeper 不能保证每次服务请求都是可达的。 从 Zookeeper 的实际应用情况来看,在使用 Zookeeper 获取服务列表时,如果此时的 Zookeeper 集群中的 Leader 宕机了,该集群就要进行 Leader 的选举,又或者 Zookeeper 集群中半数以上服务器节点不可用 (例如有三个节点,如果节点一检测到节点三挂了 ,节点二也检测到节点三挂了,那这个节点才算是真的挂了) ,那么将无法处理该请求。所以说,Zookeeper 不能保证服务可用性。 当然,在大多数分布式环境中,尤其是涉及到数据存储的场景,数据一致性应该是首先被保证的,这也是 Zookeeper 设计紧遵CP原则的另一个原因。 但是对于服务发现来说,情况就不太一样了,针对同一个服务,即使注册中心的不同节点保存的服务提供者信息不尽相同,也并不会造成灾难性的后果。 因为对于服务消费者来说,能消费才是最重要的,消费者虽然拿到可能不正确的服务实例信息后尝试消费一下,也要胜过因为无法获取实例信息而不去消费,导致系统异常要好 (淘宝的双十一,京东的618就是紧遵AP的最好参照) 。 当master节点因为网络故障与其他节点失去联系时,剩余节点会重新进行leader选举。问题在于,选举leader的时间太长,30~120s,而且选举期间整个zk集群都是不可用的,这就导致在选举期间注册服务瘫痪。 在云部署环境下, 因为网络问题使得zk集群失去master节点是大概率事件,虽然服务能最终恢复,但是漫长的选举事件导致注册长期不可用是不能容忍的。 zookeeper 的 CP 模型不适合注册中心 zookeeper 是一个非常优秀的项目,非常成熟,被大量的团队使用,但对于服务发现来讲,zookeeper 真的是一个错误的方案。 在 CAP 模型中,zookeeper 是 CP,意味着面对网络分区时,为了保持一致性,他是不可用的。 ...

2021-12-28 · 2 min · 348 words · -

TCP 拥塞控制算法, CUBIC, BBR

BBR 检查是否已经开启了 BBR # 如果结果中带有bbr,则证明你的内核已开启 bbr。 sysctl net.ipv4.tcp_available_congestion_control BBR 对 TCP 性能的提升是巨大的,它能更有效地使用当下网络环境,Youtube 应用后在吞吐量上有平均 4% 提升 (对于日本这样的网络环境有 14% 以上的提升) 报文的往返时延 RTT 降低了 33%,这样如视频这样的大文件传输更快,用户体验更好: 不像 CUBIC 这种基于丢包做拥塞控制,常导致瓶颈路由器大量报文丢失,所以重新缓存的平均间隔时间也有了 11%提升: 在 Linux 4.19 内核中已经将拥塞控制算法从 CUBIC (该算法从 2.6.19 内核就引入 Linux了)改为 BBR, 而即将面世的基于 UDP 的 HTTP3 也使用此算法。许多做应用开发的同学可能并不清楚什么是拥塞控制,BBR 算法到底在做什么, 我在《Web协议详解与抓包实战》这门课程中用了 6 节课在讲相关内容,这里我尝试下用一篇图片比文字还多的文章把这个事说清楚。 TCP 协议是面向字符流的协议,它允许应用层基于 read/write 方法来发送、读取任意长的字符流: 但 TCP 之下的 IP 层是基于块状的 Packet 报文来分片发送的,因此, TCP 协议需要将应用交付给它的字符流拆分成多个 Packet (在 TCP 传输层被称为 Segment)发送,由于网速有变化且接收主机的处理性能有限, TCP 还要决定何时发送这些 Segment。TCP 滑动窗口解决了 Client、Server 这两台主机的问题, 但没有去管连接中大量路由器、交换机转发 IP 报文的问题,因此当瓶颈路由器的输入流大于其输出流时,便会发生拥塞 ...

2021-11-17 · 2 min · 393 words · -

关于本站/关于我

关于本站/关于我/About 本站主要是个人使用的读书笔记,因为早期使用了 Wordpress 所以申请了域名, 转到 Github + Markdown 后也保留了公开访问, 本人使用频率比较高的技术文档都有仔细整理和验证过,希望能帮助到有需要的同学。当然…也有大量的转载未整理的内容,在不断完善整理中… 收集综合症/转载 基本上是我接触过的知识的一个集合 大部分内容是转载的 70%+ 一般第一次接触的知识会找质量比较好的或者能解决问题的文章收集进来 有一部分原因是防止源站消失 (比如…已经消失的一个站点http://www.yining.org/2010/05/04/http-get-vs-post-and-thoughts/),还有方便查找,省掉重新 Google 的过程。 有仔细读过的会修正 typo 日常遇到问题会逐渐整理,也会补充其它引用来源 有明显整理痕迹的都是仔细读过的,比如有段落标题,有代码语法高亮。 会有合并摘抄 一篇文章可能有多个引用来源, 对同一个问题也有可能有相互矛盾的来源,会补充验证后的结果。 前期不太注意知识共享协议,最近在有意识的识别有共享协议的文章并按协议转载 没有明显的知识共享协议的文章会逐渐转移到私有仓库 Obsidian + AWS S3 转载内容的 Author 会标记为 “-” 会不定期删除本人使用频率低的内容, 比如早期接触过的 ASP.net, Wordpress, PHP… 本站点对应的 GitHub 仓库: https://github.com/wiloon/wiloon.com 转载内容有侵权可以随时联系我删除 整理过的 在转载文章的基础上整理过的 记录了一部分常用的命令 平时经常使用的工具, 命令, 脚本, 使用过程中遇到问题,解决问题的过程中会频繁修改,会补充命令的示例 一般会有语法高亮 有段落标注 可能有 N 个引用来源 以 Tag(remix) 方式标记整理过的转载内容 – 逐渐整理中,要花些时间从收集的文档里捞出来。 日常记录 少量的原创文章或原创比例比较高的文档 日常遇到的问题和解决过程 以 Tag(original) 方式标记 – 逐渐整理中,要花些时间从收集的文档里捞出来。 Author 会标记为 “w1100n” Blog 实现 Markdown GitHub GitHub Action Hugo Even theme Nginx Bandwagon VPS Cloudflare 关于我 王越 ...

2021-11-16 · 1 min · 208 words · W10N

Chubby

Chubby 分布式锁管理系统,也可理解为一个小型强一致性文件系统 http://www.cnblogs.com/linhaohong/archive/2012/11/26/2789394.html 随着云计算的推广,云平台的设计和实现越来越复杂,很多系统属性如一致性和可靠性往往是在系统迭代开发时才被考虑到。如果在原生的系统上重复的实现复杂的一致性算法,这样不仅会破坏原有设计的结构,而且还带来很多开发上的负担。因此很多系统开发人员和架构师努力地进行系统划分,将系统分割成很多组件,分层设计,模块调用,从而最大限度地提高软件复用能力,降低系统设计和开发的难度。 Google在系统的可靠性方面提出了中心化的组件Chubby—粗粒度锁服务,通过锁原语为其他系统实现更高级的服务,比如组成员、域名服务和leader选举等等。Chubby本身也是一个小型的cell (通常由5个chubby结点组成) ,cell内部采用类似于状态机副本形式实现可靠容错。Google的Chubby论文在OSDI上发表后引起了很大的反响,原因很多,主要有两个: 第一,chubby很好的解决了分布式开发的一致性问题; 第二,Google Chubby采用Leslie Lamport提出的paxos算法来实现可靠容错,这是业界关于paxos第一个完整可行的实现。正因为Google Chubby,paxos这个一直沉淀在学术研究的协议,终于曝光在工业界中,之后很快地推广开去。 然而, Google Chubby 并不是开源的, 我们只能通过其论文和其他相关的文档中了解具体的细节。值得庆幸的是,Yahoo!借鉴 Chubby 的设计思想开发了 Zookeeper, 并将其开源。 和 Chubby 相比, Zookeeper 做了很多突破。不像 Chubby 的单点服务的结构, zookeeper 采用多个 server 同时处理客户端的请求, 异步读同步写, 通过 primary 节点来同步数据的 update, 这一点大大改善了读服务的性能, 当然弱化了客户端与服务器之间的一致性。另外, zookeeper 采用 block free 的服务接口, 采用 watch 机制的方式异步处理请求结果和指定数据的变更。Zookeeper 对外提供了更加低级的原语 primitive, 基于此可以实现更多更加复杂的分布式算法, 如 queue、barrier 和 lock 等等。 如今很多云计算系统或者平台都使用 Zookeeper 来做可靠容错, 进行订阅分发服务, 或者其他应用。 和Chubby一样,zookeeper采用paxos的变种来实现消息传输的一致性。Zookeeper开发了原子多播协议 Zab 来实现数据的一致性传输。Zookeeper采用的是primary-backup的结构,primary节点产生non- commutative 事务,通过协议按序的广播到其他backup节点上。在节点无错的情况下,这是非常简单的事情,然而,面对复杂的网络环境,多变的软硬件条件,节点挂掉,重启,数据重复发送,这些异常很常见。Zookeeper如何做到即便是系统出现异常,也能够保证整个系统状态是一致?paxos的变种,Zookeeper的Zab协议很好的保证了这一点。 Zab 协议以epoch的方式执行 (相当与序列号) ,在每个epoch最多只有一个进程多播数据。如果某个进程执行了协议的的第一阶段,那么进程将不再接受之前还没确定提交的epoch的数据。这样一来就保证了在进程在recovery阶段不会出现丢失已提交的数据的情况。在某个epoch下,所有参加这个epoch的进程必须此epoch之前所有已经提交的数据镜像。为了保证一致性,进程在完全恢复之前必须不能广播新的事务。Zab协议的这几个特点处理了primary异常、新旧primary以及backup节点异常的情况,的确保证了primary进程原子多播的order特性。 整个Zab协议的内容分成三个阶段: Discovery、Synchronization和Broadcast阶段。 ...

2021-11-11 · 1 min · 90 words · -

Raft 一致性算法

Raft 一致性算法 raft是工程上使用较为广泛的强一致性、去中心化、高可用的分布式协议。在这里强调了是在工程上,因为在学术理论界,最耀眼的还是大名鼎鼎的Paxos。但Paxos是:少数真正理解的人觉得简单,尚未理解的人觉得很难,大多数人都是一知半解。 raft的论文,两位研究者也提到,他们也花了很长的时间来理解Paxos,他们也觉得很难理解,于是研究出了raft算法。 raft是一个共识算法 (consensus algorithm),所谓共识,就是多个节点对某个事情达成一致的看法,即使是在部分节点故障、网络延时、网络分割的情况下。这些年最为火热的加密货币 (比特币、区块链)就需要共识算法,而在分布式系统中,共识算法更多用于提高系统的容错性,比如分布式存储中的复制集 (replication),在带着问题学习分布式系统之中心化复制集一文中介绍了中心化复制集的相关知识。raft协议就是一种leader-based的共识算法,与之相应的是leaderless的共识算法。 本文基于论文In Search of an Understandable Consensus Algorithm对raft协议进行分析,当然,还是建议读者直接看论文。 本文地址:https://www.cnblogs.com/xybaby/p/10124083.html raft算法概览 回到顶部 Raft算法的头号目标就是容易理解 (UnderStandable),这从论文的标题就可以看出来。当然,Raft增强了可理解性,在性能、可靠性、可用性方面是不输于Paxos的。 Raft more understandable than Paxos and also provides a better foundation for building practical systems 为了达到易于理解的目标,raft做了很多努力,其中最主要是两件事情: 问题分解 状态简化 问题分解是将"复制集中节点一致性"这个复杂的问题划分为数个可以被独立解释、理解、解决的子问题。在raft,子问题包括,leader election, log replication,safety,membership changes。而状态简化更好理解,就是对算法做出一些限制,减少需要考虑的状态数,使得算法更加清晰,更少的不确定性 (比如,保证新选举出来的leader会包含所有commited log entry) Raft implements consensus by first electing a distinguished leader, then giving the leader complete responsibility for managing the replicated log. The leader accepts log entries from clients, replicates them on other servers, and tells servers when it is safe to apply log entries to their state machines. A leader can fail or become disconnected from the other servers, in which case a new leader is elected. ...

2021-11-08 · 6 min · 1101 words · -

nuxt

nuxt https://www.nuxtjs.cn/guide/installation npx create-nuxt-app foo 服务端渲染 (SSR) 服务端渲染 (Server-Side Rendering),是指由服务侧完成页面的 HTML 结构拼接的页面处理技术,发送到浏览器,然后为其绑定状态与事件,成为完全可交互页面的过程。 优势: 对SEO友好,减小了http请求次数,加速了页面初次渲染速度 缺点: 不灵活,先后端耦合度过高 SSR 常用于以下两个场景: 有 SEO 诉求,用在搜索引擎检索以及社交分享,用在前台类应用。 首屏渲染时长有要求,常用在移动端、弱网情况下。 客户端渲染 (BSR) 前端利用ajax等数据交互手段获取服务端提供的数据以后,渲染到HTML页面。 客户端运行了页面以后才进行json 优势:灵活,真正的先后端分离,方便于先后台各自更新维护后端 缺点: 对SEO不友好,增长了http请求次数,减缓了页面加载速度 什么是预渲染 服务端渲染,首先得有后端服务器 (一般是 Node.js)才可以使用,如果我没有后端服务器,也想用在上面提到的两个场景,那么推荐使用预渲染。 预渲染与服务端渲染唯一的不同点在于渲染时机,服务端渲染的时机是在用户访问时执行渲染 (即服务时渲染,数据一般是最新的),预渲染的时机是在项目构建时,当用户访问时,数据不一定是最新的 (如果数据没有实时性,则可以直接考虑预渲染)。 预渲染 (Pre Render)在构建时执行渲染,将渲染后的 HTML 片段生成静态 HTML 文件。无需使用 web 服务器实时动态编译 HTML,适用于静态站点生成。 https://umijs.org/zh-CN/docs/ssr#%E4%BB%80%E4%B9%88%E6%98%AF%E6%9C%8D%E5%8A%A1%E7%AB%AF%E6%B8%B2%E6%9F%93%EF%BC%9F yarn add echarts vue-echarts yarn add -D @vue/composition-api yarn add -D @nuxtjs/composition-api

2021-11-02 · 1 min · 59 words · -

linux 报文高速捕获技术对比, napi/libpcap/afpacket/pfring/dpdk/xdp

linux 报文高速捕获技术对比, napi/libpcap/afpacket/pfring/dpdk/xdp 传统linux网络协议栈流程和性能分析 Linux网络协议栈是处理网络数据包的典型系统,它包含了从物理层直到应用层的全过程。 数据包到达网卡设备。 网卡设备依据配置进行DMA操作。 (第1次拷贝:网卡寄存器->内核为网卡分配的缓冲区 ring buffer) 网卡发送中断,唤醒处理器。 驱动软件从ring buffer中读取,填充内核skbuff结构 (第2次拷贝:内核网卡缓冲区ring buffer->内核专用数据结构skbuff) 数据报文达到内核协议栈,进行高层处理。 socket系统调用将数据从内核搬移到用户态。(第3次拷贝:内核空间->用户空间) 研究者们发现,Linux内核协议栈在数据包的收发过程中,内存拷贝操作的时间开销占了整个处理过程时间开销的65%,此外层间传递的系统调用时间也占据了8%~10%。 协议栈的主要问题: 针对单个数据包级别的资源分配和释放 每当一个数据包到达网卡,系统就会分配一个分组描述符用于存储数据包的信息和头部,直到分组传送到用户态空间,其描述符才被释放。此外,sk_buff 庞大的数据结构中的大部分信息对于大多数网络任务而言都是无用的. 流量的串行访问 现代网卡包括多个硬件的接收端扩展(receiver-side scaling, RSS)队列可以将分组按照五元组散列函数分配到不同的接收队列。使用这种技术,分组的捕获过程可以被并行化,因为每个RSS队列可以映射到一个特定的CPU核,并且可以对应相应的NAPI线程。这样整个捕获过程就可以做到并行化。 但是问题出现在之上的层次,Linux中的协议栈在网络层和传输层需要分析合并的所有数据包 ①所有流量在一个单一模块中被处理,产生性能瓶颈; ②用户进程不能够从一个单一的RSS队列接收消息. 这就造成了上层应用无法利用现代硬件的并行化处理能力,这种在用户态分配流量先后序列的过程降低了系统的性能,丢失了驱动层面所获得的加速. 此外,从不同队列合并的流量可能会产生额外的乱序分组 从驱动到用户态的数据拷贝 从网卡收到数据包到应用取走数据的过程中,存在至少2次数据包的复制 内核到用户空间的上下文切换 从应用程序的视角来看,它需要执行系统调用来接收每个分组.每个系统调用包含一次从用户态到内核态的上下文切换,随之而来的是大量的CPU时间消耗.在每个数据包上执行系统调用时产生的上下文切换可能消耗近1 000个CPU周期. 跨内存访问 例如,当接收一个64 B分组时,cache未命中造成了额外13.8%的CPU周期的消耗.另外,在一个基于NUMA的系统中,内存访问的时间取决于访问的存储节点.因此,cache未命中在跨内存块访问环境下会产生更大的内存访问延迟,从而导致性能下降. 提高捕获效率的技术 目前高性能报文捕获引擎中常用的提高捕获效率的技术,这些技术能够克服之前架构的性能限制. 预分配和重用内存资源 这种技术包括: 开始分组接收之前,预先分配好将要到达的数据包所需的内存空间用来存储数据和元数据(分组描述符).尤其体现在,在加载网卡驱动程序时就分配好 N 个描述符队列(每个硬件队列和设备一个). 同样,当一个数据包被传送到用户空间,其对应的描述符也不会被释放,而是重新用于存储新到达的分组.得益于这一策略,在每个数据包分配/释放所产生的性能瓶颈得到了消除.此外,也可以通过简化 sk_buff 的数据结构来减少内存开销. 数据包采用并行直接通道传递. 为了解决序列化的访问流量,需要建立从RSS队列到应用之间的直接并行数据通道.这种技术通过特定的RSS队列、特定的CPU核和应用三者的绑定来实现性能的提升. 这种技术也存在一些缺点: ①数据包可能会乱序地到达用户态,从而影响某些应用的性能; ②RSS使用Hash函数在每个接收队列间分配流量.当不同核的数据包间没有相互关联时,它们可以被独立地分析,但如果同一条流的往返数据包被分配到不同的CPU核上时,就会造成低效的跨核访问. 内存映射. 使用这种方法,应用程序的内存区域可以映射到内核态的内存区域,应用能够在没有中间副本的情况下读写这片内存区域. 用这种方式我们可以使应用直接访问网卡的DMA内存区域,这种技术被称为零拷贝.但零拷贝也存在潜在的安全问题,向应用暴露出网卡环形队列和寄存器会影响系统的安全性和稳定性 . 数据包的批处理. 为了避免对每个数据包的重复操作的开销,可以使用对数据包的批量处理. 这个策略将数据包划分为组,按组分配缓冲区,将它们一起复制到内核/用户内存.运用这种技术减少了系统调用以及随之而来的上下文切换的次数;同时也减少了拷贝的次数,从而减少了平摊到处理和复制每个数据包的开销. 但由于分组必须等到一个批次已满或定时器期满才会递交给上层,批处理技术的主要问题是延迟抖动以及接收报文时间戳误差的增加. 亲和性与预取. 由于程序运行的局部性原理,为进程分配的内存必须与正在执行它的处理器操作的内存块一致,这种技术被称为内存的亲和性. CPU亲和性是一种技术,它允许进程或线程在指定的处理器核心上运行. 在内核与驱动层面,软件和硬件中断可以用同样的方法指定具体的CPU核或处理器来处理,称为中断亲和力.每当一个线程希望访问所接收的数据,如果先前这些数据已被分配到相同CPU核的中断处理程序接收,则它们在本地cache能够更容易被访问到. 典型收包引擎 3.1 libpcap 参考:libpcap实现机制及接口函数 libpcap的包捕获机制是在数据链路层增加一个旁路处理,不干扰系统自身的网路协议栈的处理,对发送和接收的数据包通过Linux内核做过滤和缓冲处理,最后直接传递给上层应用程序。 ...

2021-10-31 · 2 min · 286 words · -

tcp proxy

tcp proxy https://github.com/jpillora/go-tcp-proxy TCP半开连接与半闭连接 https://www.cnblogs.com/cangqinglang/p/9558236.html half-open connection, 半开连接 https://bbs.huaweicloud.com/blogs/301407 处于 establish 状态的服务端如果收到了客户端的 SYN 报文(注意此时的 SYN 报文其实是乱序的,因为 SYN 报文的初始化序列号其实是一个随机数),会回复一个携带了正确序列号和确认号的 ACK 报文,这个 ACK 被称之为 Challenge ACK。 接着,客户端收到这个 Challenge ACK,发现序列号并不是自己期望收到的,于是就会回 RST 报文,服务端收到后,就会释放掉该连接。 RFC 文档解释 rfc793 文档里的第 34 页里,有说到这个例子。 原文的解释我也贴出来给大家看看。 When the SYN arrives at line 3, TCP B, being in a synchronized state, and the incoming segment outside the window, responds with an acknowledgment indicating what sequence it next expects to hear (ACK 100). TCP A sees that this segment does not acknowledge anything it sent and, being unsynchronized, sends a reset (RST) because it has detected a half-open connection. TCP B aborts at line 5. TCP A willcontinue to try to establish the connection;

2021-10-02 · 1 min · 112 words · -

JMM, Java Memory Model, java 内存模型

JMM, Java Memory Model, java 内存模型 Java内存模型,是指Java程序在运行时内存的模型,而Java代码是运行在Java虚拟机之上的,由Java虚拟机通过解释执行(解释器)或编译执行(即时编译器)来完成, 所以Java内存模型,也就是指Java虚拟机的运行时内存模型。 Java内存比较流行的说法便是堆和栈,这其实是非常粗略的一种划分,这种划分的"堆"对应内存模型的Java堆,“栈"是指虚拟机栈,然而Java内存模型远比这更复杂 @startuml skinparam componentStyle rectangle skinparam nodesep 10 skinparam ranksep 10 component "Java Run-time Data Areas" { [heap] component thread0 { [PC Register] as pc0 [thread stack] as ts0 [Native Method Stack] as nms0 pc0 -[hidden]-> ts0 ts0 -[hidden]-> nms0 } component thread1 { [PC Register] as pc1 [thread stack] as ts1 [Native Method Stack] as nms1 pc1 -[hidden]-> ts1 ts1 -[hidden]-> nms1 } thread0 --[hidden]--> heap thread1 --[hidden]--> heap component "method area" as ma { [constant pool] as cp } heap -[hidden]-> ma } @enduml Java 虚拟机的内存空间 (运行时数据区)分为 5 个部分: 程序计数器, PC register Java 虚拟机栈, JVM stack, 线程栈, thread stack 本地方法栈, native method stack 堆, heap 方法区, method area,方法区里面还有一个常量池 线程私有的数据区: 程序计数器,虚拟机栈,本地方法栈 所有线程共有的数据区: Java堆,方法区 ...

2021-09-21 · 3 min · 596 words · -

VarHandle

“VarHandle” VarHandle 的出现替代了java.util.concurrent.atomic和sun.misc.Unsafe的部分操作。并且提供了一系列标准的内存屏障操作,用于更加细粒度的控制内存排序。在安全性、可用性、性能上都要优于现有的API。VarHandle 可以与任何字段、数组元素或静态变量关联,支持在不同访问模型下对这些类型变量的访问,包括简单的 read/write 访问,volatile 类型的 read/write 访问,和 CAS(compare-and-swap)等。 Unsafe 是不建议开发者直接使用的,因为 Unsafe 所操作的并不属于Java标准,会容易带来一些安全性的问题。JDK9 之后,官方推荐使用 java.lang.invoke.Varhandle 来替代 Unsafe 大部分功能,对比 Unsafe ,Varhandle 有着相似的功能,但会更加安全,并且,在并发方面也提高了不少性能。 Varhandle是对变量或参数定义的变量系列的动态强类型引用,包括静态字段,非静态字段,数组元素或堆外数据结构的组件。 在各种访问模式下都支持访问这些变量,包括简单的读/写访问,volatile 的读/写访问以及 CAS (compare-and-set)访问。简单来说 Variable 就是对这些变量进行绑定,通过 Varhandle 直接对这些变量进行操作。 import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.Arrays; public class VarHandleX { public int publicVar = 1; protected int protectedVar = 2; @SuppressWarnings("FieldMayBeFinal") private int privateVar = 3; public int[] arrayData = new int[]{1, 2, 3}; @Override public String toString() { return "VarHandleX{" + "publicVar=" + publicVar + ", protectedVar=" + protectedVar + ", privateVar=" + privateVar + ", arrayData=" + Arrays.toString(arrayData) + '}'; } public static void main(String[] args) { try { VarHandleX instance = new VarHandleX(); VarHandle varHandle = MethodHandles.privateLookupIn(VarHandleX.class, MethodHandles.lookup()) .findVarHandle(VarHandleX.class, "privateVar", int.class); varHandle.set(instance, 33); System.out.println(instance); protectedDemo(); protectedDemo2(); publicDemo(); arrayDemo(); } catch (NoSuchFieldException | IllegalAccessException e) { e.printStackTrace(); } } private static void protectedDemo() throws NoSuchFieldException, IllegalAccessException { VarHandleX instance = new VarHandleX(); VarHandle varHandle = MethodHandles.privateLookupIn(VarHandleX.class, MethodHandles.lookup()) .findVarHandle(VarHandleX.class, "protectedVar", int.class); varHandle.set(instance, 22); System.out.println("protected: " + instance); } private static void protectedDemo2() throws NoSuchFieldException, IllegalAccessException { VarHandleX instance = new VarHandleX(); VarHandle varHandle = MethodHandles.lookup() .in(VarHandleX.class) .findVarHandle(VarHandleX.class, "protectedVar", int.class); varHandle.set(instance, 22); System.out.println("protected 2: " + instance); } private static void publicDemo() throws NoSuchFieldException, IllegalAccessException { VarHandleX instance = new VarHandleX(); VarHandle varHandle = MethodHandles.lookup() .in(VarHandleX.class) .findVarHandle(VarHandleX.class, "publicVar", int.class); varHandle.set(instance, 11); System.out.println("public: " + instance); } private static void arrayDemo() throws NoSuchFieldException, IllegalAccessException { VarHandleX instance = new VarHandleX(); VarHandle arrayVarHandle = MethodHandles.arrayElementVarHandle(int[].class); arrayVarHandle.compareAndSet(instance.arrayData, 0, 1, 11); arrayVarHandle.compareAndSet(instance.arrayData, 1, 2, 22); arrayVarHandle.compareAndSet(instance.arrayData, 2, 3, 33); System.out.println("array: " + instance); } } 获取Varhandle方式汇总 MethodHandles.privateLookupIn(class, MethodHandles.lookup())获取访问私有变量的Lookup MethodHandles.lookup() 获取访问protected、public的Lookup findVarHandle: 用于创建对象中非静态字段的VarHandle。接收参数有三个,第一个为接收者的class对象,第二个是字段名称,第三个是字段类型。 findStaticVarHandle: 用于创建对象中静态字段的VarHandle,接收参数与findVarHandle一致。 unreflectVarHandle: 通过反射字段Field创建VarHandle。 MethodHandles.arrayElementVarHandle(int[].class) 获取管理数组的 Varhandle 功能 VarHandle来使用plain、opaque、release/acquire和volatile四种共享内存的访问模式,根据这四种共享内存的访问模式又分为写入访问模式、读取访问模式、原子更新访问模式、数值更新访问模式、按位原子更新访问模式。 ...

2021-09-21 · 4 min · 655 words · -

Unsafe

“Unsafe” unsafe Unsafe在sun.misc 下,顾名思义,这是一个不安全的类,因为Unsafe类所操作的并不属于Java标准,Java的一系列内存操作都是交给jvm的,而Unsafe类却能有像C语言的指针一样直接操作内存的能力,同时也会带来了指针的问题。过度使用Unsafe类的话,会使出错率变得更大,因此官方才命名为Unsafe,并且不建议使用,连注释的没有。 而为了安全使用Unsafe,Unsafe类只允许jdk自带的类使用,从下面的代码中可以看出 public static Unsafe getUnsafe() { Class<?> caller = Reflection.getCallerClass(); if (!VM.isSystemDomainLoader(caller.getClassLoader())) throw new SecurityException("Unsafe"); return theUnsafe; } 如果当前Class是非系统加载的(也就是caller.getClassLoader()不为空),直接抛出SecurityException 。 在java9之后,又出现了一个jdk.internal.misc.Unsafe类,其功能与sun.misc.Unsafe类是一样的,唯一不一样的是在 getSafe() 的时候,jdk.internal.misc.Unsafe是没有做校验的,但是jdk包下的代码,应用开发时是不能直接调用的,而且在java9之后,两个Unsafe类都有充足的注释。 JUC紧密使用了Unsafe的功能。 功能简介 Unsafe类的功能主要分为内存操作、CAS、Class相关、对象操作、数组相关、内存屏障、系统相关、线程调度等功能。 内存操作 堆外(native memory)内存操作 //分配内存,并返回内存地址 public native long allocateMemory(long bytes); //扩充内存,address可以是allocateMemory方法返回的地址,bytes是扩充的大小 public native long reallocateMemory(long address, long bytes); //释放内存 public native void freeMemory(long address); //在给定的内存块设置默认值 public native void setMemory(long address, long bytes, byte value); //获取指定地址值的byte类型 public native byte getByte(long address); //设置堆外指定值的byte类型的值 public native void putByte(long address, byte x); ...

2021-09-20 · 3 min · 440 words · -

Spring Cloud

“Spring Cloud” Eureka [jʊ’ri:kə] Ribbon [ˈrɪbən] Feign [fen] Hystrix [hɪst’rɪks] Zuul [zulu] Sleuth [sluθ] Turbine [ˈtɜ:rbaɪn] Spring Cloud Netflix (Eureka、Hystrix、Zuul、Archaius) 、Spring Cloud Config、Spring Cloud Bus、Spring Cloud Cluster、Spring Cloud Consul、Spring Cloud Security、Spring Cloud Sleuth、Spring Cloud Data Flow、Spring Cloud Stream、Spring Cloud Task、Spring Cloud Zookeeper、Spring Cloud Connectors、Spring Cloud Starters、Spring Cloud CLI Eureka: 服务注册中心,一个基于REST的服务,用于定位服务,以实现微服务架构中服务发现和故障转移。 Hystrix: 熔断器,容错管理工具,旨在通过熔断机制控制服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。 l Turbine: Turbine是聚合服务器发送事件流数据的一个工具,用来监控集群下Hystrix的Metrics情况。 l Zuul: API网关,Zuul是在微服务中提供动态路由、监控、弹性、安全等边缘服务的框架。 l Ribbon: 提供微服务中的负载均衡功能,有多种负载均衡策略可供选择,可配合服务发现和断路器使用。 l Feign: Feign是一种声明式、模板化的HTTP客户端。 l Spring Cloud Config: 配置管理工具包,让你可以把配置放到远程服务器,集中化管理集群配置,目前支持本地存储、Git以及Subversion。 l Spring Cloud Security: 基于Spring Security的安全工具包,为微服务的应用程序添加安全控制。 ...

2021-09-14 · 1 min · 140 words · -

服务治理

“服务治理” https://coolshell.me/articles/talking-about-service-governance-microservices-and-service-mesh.html 服务治理,也称为SOA治理,是指用来管理SOA的采用和实现的过程。 服务定义 (服务的范围、接口和边界) 服务部署生命周期 (各个生命周期阶段) 服务版本治理 (包括兼容性) 服务迁移 (启用和退役) 服务注册中心 (依赖关系) 服务消息模型 (规范数据模型) 服务监视 (进行问题确定) 服务所有权 (企业组织) 服务测试 (重复测试) 服务安全 (包括可接受的保护范围) Dubbo开源 直到2011年10月27日,阿里巴巴开源了自己的SOA服务化治理方案的核心框架Dubbo,服务治理和SOA的设计理念开始逐渐在国内软件行业中落地,并被广泛应用。

2021-09-14 · 1 min · 25 words · -