<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Service Mesh on Lynskylate&#39;s Blog</title>
    <link>https://lynskylate.github.io/tags/service-mesh/</link>
    <description>Recent content in Service Mesh on Lynskylate&#39;s Blog</description>
    <generator>Hugo</generator>
    <language>zh-CN</language>
    <copyright>Copyright © 2019, lynskylate; all rights reserved.</copyright>
    <lastBuildDate>Wed, 09 Jan 2019 23:18:43 +0800</lastBuildDate>
    <atom:link href="https://lynskylate.github.io/tags/service-mesh/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Envoy的线程模型[翻译]</title>
      <link>https://lynskylate.github.io/post/envoy_thread/</link>
      <pubDate>Wed, 09 Jan 2019 23:18:43 +0800</pubDate>
      <guid>https://lynskylate.github.io/post/envoy_thread/</guid>
      <description>&lt;h1 id=&#34;envoy-threading-model&#34;&gt;Envoy threading Model&lt;/h1&gt;&#xA;&lt;p&gt;关于envoy 代码的底层文档相当稀少。为了解决这个问题我计划编写一系列文档来描述各个子系统的工作。由于是第一篇， 请让我知道你希望其他主题覆盖哪些内容。&lt;/p&gt;&#xA;&lt;p&gt;一个我所了解到最共同的技术问题是关于envoy使用的线程模型的底层描述，这篇文章将会描述envoy如何使用线程来处理连接的(how envoy maps connections to threads)， 同事也会描述Thread Local Storage(TLS)系统是如何使内部代码平行且高效的。&lt;/p&gt;&#xA;&lt;h2 id=&#34;threading-overview&#34;&gt;Threading overview&lt;/h2&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://lynskylate.github.io/images/envoy_thread/01.png&#34; alt=&#34;img&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;Figure 1: Threading overview&lt;/p&gt;&#xA;&lt;p&gt;如同图一所示，envoy使用了三中不同类型的线程。&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;Main&lt;/strong&gt;: 这个线程管理了服务器本身的启动和终止, 所有&lt;a href=&#34;https://github.com/envoyproxy/data-plane-api/blob/master/XDS_PROTOCOL.md&#34;&gt;xDS API&lt;/a&gt;的处理(包括DNS, 健康检查(health checking) 和通常的集群管理), running, 监控刷新(stat flushing), 管理界面 还有 通用的进程管理(signals, &lt;a href=&#34;https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/hot_restart.html&#34;&gt;hot restart&lt;/a&gt;。在这个线程中发生的所有事情都是异步和非阻塞的(non blocking)。通常，主线程用来协调所有不需要大量cpu完成的关键功能。这允许大部分代码编写的如同单线程一样。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;Worker&lt;/strong&gt; 在envoy系统中，默认为每个硬件(every harware)生成一个worker线程（可以通过&amp;ndash;concurrency参数控制),每个工作线程运行一个无阻塞的事件循环(event loop)，for listening on every listener (there is currently no listener sharding), accept 新的连接，为每个连接实例化过滤栈，以及处理这个连接生命周期的所有io。同时，也允许所有连接代码编写的如同单线程一样。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;File flusher&lt;/strong&gt; Envoy 写入的每个文件现在都有一个单独的block的刷新线程。这是因为使用O_NONBLOCK在写入文件系统有时也会阻塞。当Worker线程需要写入文件时，这个数据实际上被移动至in-memory buffer中，最终会被File Flusher线程刷新至文件中。envoy的代码会在一个worker试图写入memory buffer时锁住所有worker。还有一些其他的会在下面讨论。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;连接处理&#34;&gt;连接处理&lt;/h2&gt;&#xA;&lt;p&gt;如上所述， 所有worker线程都会监听端口而没有任何分片，因此，内核智能的分配accept的套接字给worker进程。现代内核一般都很擅长这一点，在开始使用其他监听同一套接字的其他线程之前，内核使用io 优先级提升等特性来分配线程的工作，同样的还有不适用spin-lock来如理所有请求。&lt;/p&gt;&#xA;&lt;p&gt;一旦woker accept了一个连接，那么这个连接永远不会离开这个worker(一个连接只由同一worker进行处理), 所有关于连接的处理都将会在worker线程内进一步处理，包括任何转发行为。这有一些重要的含义：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Envoy连接池中都是worker线程，因此通过http/2 连接池每次只与上游主机建立一个连接，如果有4个worker，那在稳定状态将只有四个http/2连接与上游主机进行连接。&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
