<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/rss.xsl" type="text/xsl"?>
<rss version="2.0">
  <channel>
    <title>IT瘾笔记推荐</title>
    <link>https://itindex.net/tags/笔记</link>
    <description>IT社区推荐资讯 - ITIndex.net</description>
    <language>zh</language>
    <copyright>https://itindex.net/</copyright>
    <generator>https://itindex.net/</generator>
    <docs>http://backend.userland.com/rss</docs>
    <image>
      <url>https://itindex.net/images/logo.gif</url>
      <title>IT社区推荐资讯 - ITIndex.net</title>
      <link>https://itindex.net/tags/笔记</link>
    </image>
    <item>
      <title>用 Wireshark 分析 TCP 吞吐瓶颈</title>
      <link>https://itindex.net/detail/62372-wireshark-%E5%88%86%E6%9E%90-tcp</link>
      <description>&lt;p&gt;Debug 网络质量的时候，我们一般会关注两个因素：延迟和吞吐量（带宽）。延迟比较好验证，Ping 一下或者   &lt;a href="https://www.kawabangga.com/posts/4275"&gt;mtr&lt;/a&gt; 一下就能看出来。这篇文章分享一个 debug 吞吐量的办法。&lt;/p&gt;
 &lt;p&gt;看重吞吐量的场景一般是所谓的长肥管道(Long Fat Networks, LFN,   &lt;a href="https://datatracker.ietf.org/doc/html/rfc7323"&gt;rfc7323&lt;/a&gt;). 比如下载大文件。吞吐量没有达到网络的上限，主要可能受 3 个方面的影响：&lt;/p&gt;
 &lt;ol&gt;
  &lt;li&gt;发送端出现了瓶颈&lt;/li&gt;
  &lt;li&gt;接收端出现了瓶颈&lt;/li&gt;
  &lt;li&gt;中间的网络层出现了瓶颈&lt;/li&gt;
&lt;/ol&gt;
 &lt;p&gt;发送端出现瓶颈一般的情况是 buffer 不够大，因为发送的过程是，应用调用 syscall，将要发送的数据放到 buffer 里面，然后由系统负责发送出去。如果 buffer 满了，那么应用会阻塞住（如果使用 block 的 API 的话），直到 buffer 可用了再继续 write，生产者和消费者模式。&lt;/p&gt;
 &lt;div&gt;  &lt;a href="https://www.kawabangga.com/wp-content/uploads/2022/08/tcp-bufer.gif"&gt;   &lt;img alt="" height="298" src="https://www.kawabangga.com/wp-content/uploads/2022/08/tcp-bufer.gif" width="266"&gt;&lt;/img&gt;&lt;/a&gt;  &lt;p&gt;图片来自    &lt;a href="https://www.ciscopress.com/articles/article.asp?p=769557&amp;seqNum=2"&gt;cisco&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;
 &lt;p&gt;发送端出现瓶颈一般都比较好排查，甚至通过应用的日志看何时阻塞住了即可。大部分情况都是第 2，3 种情况，比较难以排查。这种情况发生在，发送端的应用已经将内容写入到了系统的 buffer 中，但是系统并没有很快的发送出去。&lt;/p&gt;
 &lt;p&gt;TCP 为了优化传输效率（注意这里的传输效率，并不是单纯某一个 TCP 连接的传输效率，而是整体网络的效率），会:&lt;/p&gt;
 &lt;ol&gt;
  &lt;li&gt;保护接收端，发送的数据不会超过接收端的 buffer 大小 (Flow control)。数据发送到接受端，也是和上面介绍的过程类似，kernel 先负责收好包放到 buffer 中，然后上层应用程序处理这个 buffer 中的内容，如果接收端的 buffer 过小，那么很容易出现瓶颈，即应用程序还没来得及处理就被填满了。那么如果数据继续发过来，buffer 存不下，接收端只能丢弃。&lt;/li&gt;
  &lt;li&gt;保护网络，发送的数据不会 overwhelming 网络 (Congestion Control, 拥塞控制), 如果中间的网络出现瓶颈，会导致长肥管道的吞吐不理想；&lt;/li&gt;
&lt;/ol&gt;
 &lt;p&gt;对于接收端的保护，在两边连接建立的时候，会协商好接收端的 buffer 大小 (receiver window size, rwnd), 并且在后续的发送中，接收端也会在每一个 ack 回包中报告自己剩余和接受的 window 大小。这样，发送端在发送的时候会保证不会发送超过接收端 buffer 大小的数据。（意思是，发送端需要负责，receiver 没有 ack 的总数，不会超过 receiver 的 buffer.）&lt;/p&gt;
 &lt;div&gt;  &lt;a href="https://www.kawabangga.com/wp-content/uploads/2022/08/receiver-buffer.gif"&gt;   &lt;img alt="" height="388" src="https://www.kawabangga.com/wp-content/uploads/2022/08/receiver-buffer.gif" width="500"&gt;&lt;/img&gt;&lt;/a&gt;  &lt;p&gt;图片来自    &lt;a href="https://www.ciscopress.com/articles/article.asp?p=769557&amp;seqNum=2"&gt;cisco&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;
 &lt;p&gt;对于网络的保护，原理也是维护一个 Window，叫做 Congestion window，拥塞窗口，cwnd, 这个窗口就是当前网络的限制，发送端不会发送超过这个窗口的容量（没有 ack 的总数不会超过 cwnd）。&lt;/p&gt;
 &lt;p&gt;怎么找到这个 cwnd 的值呢？&lt;/p&gt;
 &lt;p&gt;这个就是关键了，默认的算法是 cubic, 也有其他算法可以使用，比如 Google 的   &lt;a href="https://www.kawabangga.com/posts/4086"&gt;BBR&lt;/a&gt;.&lt;/p&gt;
 &lt;p&gt;主要的逻辑是，慢启动(Slow start), 发送数据来测试，如果能正确收到 receiver 那边的 ack，说明当前网络能容纳这个吞吐，将 cwnd x 2，然后继续测试。直到下面一种情况发生：&lt;/p&gt;
 &lt;ol&gt;
  &lt;li&gt;发送的包没有收到 ACK&lt;/li&gt;
  &lt;li&gt;cwnd 已经等于 rwnd 了&lt;/li&gt;
&lt;/ol&gt;
 &lt;p&gt;第 2 点很好理解，说明网络吞吐并不是一个瓶颈，瓶颈是在接收端的 buffer 不够大。cwnd 不能超过 rwnd，不然会 overload 接收端。&lt;/p&gt;
 &lt;p&gt;对于第 1 点，本质上，发送端是用丢包来检测网络状况的，如果没有发生丢包，表示一切正常，如果发生丢包，说明网络处理不了这个发送速度，这时候发送端会直接将 cwnd 减半。&lt;/p&gt;
 &lt;p&gt;但实际造成第 1 点的情况并不一定是网络吞吐瓶颈，而可能是以下几种情况：&lt;/p&gt;
 &lt;ol&gt;
  &lt;li&gt;网络达到了瓶颈&lt;/li&gt;
  &lt;li&gt;网络质量问题丢包&lt;/li&gt;
  &lt;li&gt;中间网络设备延迟了包的送达，导致发送端没有在预期时间内收到 ACK&lt;/li&gt;
&lt;/ol&gt;
 &lt;p&gt;2 和 3 原因都会造成 cwnd 下降，无法充分利用网络吞吐。&lt;/p&gt;
 &lt;p&gt;以上就是基本的原理，下面介绍如何定位这种问题。&lt;/p&gt;
 &lt;h2&gt;rwnd 查看方式&lt;/h2&gt;
 &lt;p&gt;这个 window size 直接就在 TCP header 里面，抓下来就能看这个字段。&lt;/p&gt;
 &lt;p&gt;  &lt;a href="https://www.kawabangga.com/wp-content/uploads/2022/08/tcp-handshake-factor.png"&gt;   &lt;img alt="" height="1350" src="https://www.kawabangga.com/wp-content/uploads/2022/08/tcp-handshake-factor.png" width="2728"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;但是真正的 window size 需要乘以 factor, factor 是在   &lt;a href="https://en.wikipedia.org/wiki/TCP_window_scale_option"&gt;TCP 握手节点通过 TCP Options 协商的&lt;/a&gt;。所以如果分析一条 TCP 连接的 window size，必须抓到握手阶段的包，不然就不可以知道协商的 factor 是多少。&lt;/p&gt;
 &lt;p&gt;  &lt;a href="https://www.kawabangga.com/wp-content/uploads/2022/08/tcp-rwnd-size.png"&gt;   &lt;img alt="" height="2008" src="https://www.kawabangga.com/wp-content/uploads/2022/08/tcp-rwnd-size.png" width="2728"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;h2&gt;cwnd 查看方式&lt;/h2&gt;
 &lt;p&gt;Congestion control 是发送端通过算法得到的一个动态变量，会试试调整，并不会体现在协议的传输数据中。所以要看这个，必须在发送端的机器上看。&lt;/p&gt;
 &lt;p&gt;在 Linux 中可以使用   &lt;code&gt;ss -i&lt;/code&gt; 选项将 TCP 连接的参数都打印出来。&lt;/p&gt;
 &lt;p&gt;  &lt;a href="https://www.kawabangga.com/wp-content/uploads/2022/08/tcp-cwnd-ss.png"&gt;   &lt;img alt="" height="600" src="https://www.kawabangga.com/wp-content/uploads/2022/08/tcp-cwnd-ss.png" width="1466"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;这里展示的单位是   &lt;a href="https://www.cloudflare.com/learning/network-layer/what-is-mss/"&gt;TCP MSS.&lt;/a&gt; 即实际大小是 1460bytes * 10.&lt;/p&gt;
 &lt;h2&gt;Wireshark 分析&lt;/h2&gt;
 &lt;p&gt;Wireshark 提供了非常使用的统计功能，可以让你一眼就能看出当前的瓶颈是发生在了哪里。但是第一次打开这个图我不会看，一脸懵逼，也没查到资料要怎么看。好在我  &lt;a href="https://github.com/royzhr"&gt;同事&lt;/a&gt;会，他把我教会了，我在这里记录一下，把你也教会。&lt;/p&gt;
 &lt;p&gt;首先，打开的方式如下：&lt;/p&gt;
 &lt;p&gt;  &lt;a href="https://www.kawabangga.com/wp-content/uploads/2022/08/wireshark-open-tcptrace.png"&gt;   &lt;img alt="" height="1344" src="https://www.kawabangga.com/wp-content/uploads/2022/08/wireshark-open-tcptrace.png" width="1902"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;然后你会看到如下的图。&lt;/p&gt;
 &lt;p&gt;  &lt;a href="https://www.kawabangga.com/wp-content/uploads/2022/08/wireshark-tcptrace-howtoread.png"&gt;   &lt;img alt="" height="1238" src="https://www.kawabangga.com/wp-content/uploads/2022/08/wireshark-tcptrace-howtoread.png" width="1728"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;首先需要明确，tcptrace 的图表示的是单方向的数据发送，因为 tcp 是双工协议，两边都能发送数据。其中最上面写了你当前在看的图数据是从 10.0.0.1 发送到 192.168.0.1 的，然后按右下角的按钮可以切换看的方向。&lt;/p&gt;
 &lt;p&gt;X轴表示的是时间，很好理解。&lt;/p&gt;
 &lt;p&gt;然后理解一下 Y 轴表示的 Sequence Number, 就是 TCP 包中的 Sequence Number，这个很关键。图中所有的数据，都是以 Sequence Number 为准的。&lt;/p&gt;
 &lt;p&gt;所以，你如果看到如上图所示，那么说明你看反了，因为数据的 Sequence Number 并没有增加过，说明几乎没有发送过数据，需要点击 Switch Direction。&lt;/p&gt;
 &lt;p&gt;  &lt;a href="https://www.kawabangga.com/wp-content/uploads/2022/08/wireshark-real-dataflow.png"&gt;   &lt;img alt="" height="1238" src="https://www.kawabangga.com/wp-content/uploads/2022/08/wireshark-real-dataflow.png" width="1728"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;这就对了，可以看到我们传输的 Sequence Number 在随着时间增加而增加。&lt;/p&gt;
 &lt;p&gt;这里面有 3 条线，含义如下：&lt;/p&gt;
 &lt;p&gt;  &lt;a href="https://www.kawabangga.com/wp-content/uploads/2022/08/wireshark-tcptrace-read.png"&gt;   &lt;img alt="" height="1238" src="https://www.kawabangga.com/wp-content/uploads/2022/08/wireshark-tcptrace-read.png" width="1728"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;除此之外，另外还有两种线：&lt;/p&gt;
 &lt;p&gt;  &lt;a href="https://www.kawabangga.com/wp-content/uploads/2022/08/tcptrace-sack.png"&gt;   &lt;img alt="" height="1238" src="https://www.kawabangga.com/wp-content/uploads/2022/08/tcptrace-sack.png" width="1728"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;需要始终记住的是 Y 轴是 Sequence Number，红色的线表示 SACK 的线表示这一段 Sequence Number 我已经收到了，然后配合黄色线表示 ACK 过的 Sequence Number，那么发送端就会知道，在中间这段空挡，包丢了，红色线和黄色线纵向的空白，是没有被 ACK 的包。所以，需要重新传输。而蓝色的线就是表示又重新传输了一遍。&lt;/p&gt;
 &lt;p&gt;学会了看这些图，我们可以认识几种常见的 pattern：&lt;/p&gt;
 &lt;h3&gt;丢包&lt;/h3&gt;
 &lt;p&gt;  &lt;a href="https://www.kawabangga.com/wp-content/uploads/2022/08/wireshark-packet-loss.png"&gt;   &lt;img alt="" height="1238" src="https://www.kawabangga.com/wp-content/uploads/2022/08/wireshark-packet-loss.png" width="1728"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;很多红色 SACK，说明接收端那边重复在说：中间有一个包我没有收到，中间有一个包我没有收到。&lt;/p&gt;
 &lt;h3&gt;吞吐受到接收 window size 限制&lt;/h3&gt;
 &lt;p&gt;  &lt;a href="https://www.kawabangga.com/wp-content/uploads/2022/08/rwnd-too-low.png"&gt;   &lt;img alt="" height="1238" src="https://www.kawabangga.com/wp-content/uploads/2022/08/rwnd-too-low.png" width="1728"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;从这个图可以看出，黄色的线（接收端一 ACK）一上升，蓝色就跟着上升（发送端就开始发），直到填满绿色的线（window size）。说明网络并不是瓶颈，可以调大接收端的 buffer size.&lt;/p&gt;
 &lt;h3&gt;吞吐受到网络质量限制&lt;/h3&gt;
 &lt;p&gt;  &lt;a href="https://www.kawabangga.com/wp-content/uploads/2022/08/wireshark-cwnd-low.png"&gt;   &lt;img alt="" height="1238" src="https://www.kawabangga.com/wp-content/uploads/2022/08/wireshark-cwnd-low.png" width="1728"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;从这张图中可以看出，接收端的 window size 远远不是瓶颈，还有很多空闲。&lt;/p&gt;
 &lt;p&gt;  &lt;a href="https://www.kawabangga.com/wp-content/uploads/2022/08/wireshark-cwnd-low-zoom.png"&gt;   &lt;img alt="" height="1238" src="https://www.kawabangga.com/wp-content/uploads/2022/08/wireshark-cwnd-low-zoom.png" width="1728"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;放大可以看出，中间有很多丢包和重传，并且每次只发送一点点数据，这说明很有可能是 cwnd 太小了，受到了拥塞控制算法的限制。&lt;/p&gt;
 &lt;p&gt; &lt;/p&gt;
 &lt;p&gt;本文中用到的抓包文件可以从这里下载(credit:   &lt;a href="https://www.youtube.com/watch?v=yUmACeSmT7o"&gt;https://www.youtube.com/watch?v=yUmACeSmT7o&lt;/a&gt;):&lt;/p&gt;
 &lt;ol&gt;
  &lt;li&gt;   &lt;a href="https://www.cloudshark.org/captures/f5eb7c033728"&gt;https://www.cloudshark.org/captures/f5eb7c033728&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="https://www.cloudshark.org/captures/c967765aef38"&gt;https://www.cloudshark.org/captures/c967765aef38&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
 &lt;p&gt;其他的一些参考资料：&lt;/p&gt;
 &lt;ol&gt;
  &lt;li&gt;   &lt;a href="https://www.stackpath.com/edge-academy/what-is-cwnd-and-rwnd/"&gt;https://www.stackpath.com/edge-academy/what-is-cwnd-and-rwnd/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="https://www.baeldung.com/cs/tcp-flow-control-vs-congestion-control"&gt;https://www.baeldung.com/cs/tcp-flow-control-vs-congestion-control&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="https://www.cs.cornell.edu/courses/cs4450/2020sp/lecture21-congestion-control.pdf"&gt;https://www.cs.cornell.edu/courses/cs4450/2020sp/lecture21-congestion-control.pdf&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="https://www.mi.fu-berlin.de/inf/groups/ag-tech/teaching/2011-12_WS/L_19531_Telematics/08_Transport_Layer.pdf"&gt;https://www.mi.fu-berlin.de/inf/groups/ag-tech/teaching/2011-12_WS/L_19531_Telematics/08_Transport_Layer.pdf&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="https://wiki.aalto.fi/download/attachments/69901948/TCP-CongestionControlFinal.pdf"&gt;https://wiki.aalto.fi/download/attachments/69901948/TCP-CongestionControlFinal.pdf&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="https://paulgrevink.wordpress.com/2017/09/08/about-long-fat-networks-and-tcp-tuning/"&gt;https://paulgrevink.wordpress.com/2017/09/08/about-long-fat-networks-and-tcp-tuning/&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt; &lt;p&gt;The post   &lt;a href="https://www.kawabangga.com/posts/4794"&gt;用 Wireshark 分析 TCP 吞吐瓶颈&lt;/a&gt; first appeared on   &lt;a href="https://www.kawabangga.com"&gt;卡瓦邦噶！&lt;/a&gt;.&lt;/p&gt; &lt;div&gt;  &lt;h3&gt;相关文章:&lt;/h3&gt;  &lt;ul&gt;   &lt;li&gt;    &lt;a href="https://www.kawabangga.com/posts/1878"&gt;Django的日志配置&lt;/a&gt;&lt;/li&gt;   &lt;li&gt;    &lt;a href="https://www.kawabangga.com/posts/2029"&gt;部署Sentry&lt;/a&gt;&lt;/li&gt;   &lt;li&gt;    &lt;a href="https://www.kawabangga.com/posts/4275"&gt;使用 mtr 检查网络问题，以及注意事项&lt;/a&gt;&lt;/li&gt;   &lt;li&gt;    &lt;a href="https://www.kawabangga.com/posts/4484"&gt;Django 优化数据库查询的一些经验&lt;/a&gt;&lt;/li&gt;   &lt;li&gt;    &lt;a href="https://www.kawabangga.com/posts/837"&gt;Java 问答：终极父类（五）——toString()&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;  &lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>程序开发笔记 bbr congestion control cubic cwnd</category>
      <guid isPermaLink="true">https://itindex.net/detail/62372-wireshark-%E5%88%86%E6%9E%90-tcp</guid>
      <pubDate>Wed, 17 Aug 2022 23:24:57 CST</pubDate>
    </item>
    <item>
      <title>ComSec概念概述</title>
      <link>https://itindex.net/detail/62047-comsec-%E6%A6%82%E5%BF%B5</link>
      <description>&lt;h1&gt;  &lt;a href="https://luo41.top/#comsec&amp;#24635;&amp;#32467;"&gt;&lt;/a&gt; ComSec总结&lt;/h1&gt; &lt;p&gt;这学期选修了bintou老师的ComSec计算机安全课，上课期间觉得自己学的马马虎虎的，学习了一些计算机安全中的密码学算法和安全概念，但对这些概念都不是特别清晰，期末复习的过程中，对其中的一些算法和概念更理解了一些，趁着刚考完还没忘记，总结一波挂在博客，不当之处，欢迎指正。&lt;/p&gt; &lt;h2&gt;  &lt;a href="https://luo41.top/#&amp;#20844;&amp;#38053;&amp;#23494;&amp;#30721;&amp;#23398;&amp;#27010;&amp;#36848;"&gt;&lt;/a&gt; 公钥密码学概述&lt;/h2&gt; &lt;p&gt;公钥密码学也称为  &lt;strong&gt;非对称密码学&lt;/strong&gt;，与传统的对称密码学区别在于，加密和解密使用  &lt;strong&gt;不同的密钥&lt;/strong&gt;，也就是所说的  &lt;strong&gt;key&lt;/strong&gt;，其中公开出来的密钥是  &lt;strong&gt;公钥&lt;/strong&gt;，另一个是私钥，由持有者  &lt;strong&gt;严格保密&lt;/strong&gt;。且  &lt;strong&gt;公钥密码&lt;/strong&gt;是基于数学函数而不是基于替换和置换。&lt;/p&gt; &lt;p&gt;公钥密码学提出的解决的基本问题包括有&lt;/p&gt; &lt;ol&gt;  &lt;li&gt;密钥交换&lt;/li&gt;  &lt;li&gt;数字签名&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;公钥密码的六个组成成分分别是  &lt;strong&gt;明文&lt;/strong&gt;，  &lt;strong&gt;密文&lt;/strong&gt;，  &lt;strong&gt;公钥&lt;/strong&gt;，  &lt;strong&gt;私钥&lt;/strong&gt;，  &lt;strong&gt;加密算法&lt;/strong&gt;，  &lt;strong&gt;解密算法&lt;/strong&gt;。&lt;/p&gt; &lt;p&gt;公钥密码的重要特点是&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;仅根据密码算法和加密密钥，确定解密密钥在   &lt;strong&gt;计算上不可行&lt;/strong&gt;，所谓计算上不可行即是   &lt;code&gt;解决一个问题所需要的时间比输入规模的多项式增长更快，如输入长度为n位，计算复杂度是&lt;/code&gt;2n2^{n}2n。&lt;/li&gt;  &lt;li&gt;两个密钥中的任意一个都可用来加密，另一个用来解密，也就是说，存在两个方式，一种是   &lt;code&gt;公钥加密，私钥解密&lt;/code&gt;，一种是   &lt;code&gt;私钥加密，公钥解密&lt;/code&gt;。根据这两种方式，公钥密码体制分成了两个模式，一个是   &lt;strong&gt;加密模式&lt;/strong&gt;，一个是   &lt;strong&gt;认证模式&lt;/strong&gt;。&lt;/li&gt;&lt;/ul&gt; &lt;h3&gt;  &lt;a href="https://luo41.top/#&amp;#21152;&amp;#23494;&amp;#27169;&amp;#24335;"&gt;&lt;/a&gt; 加密模式&lt;/h3&gt; &lt;p&gt;所谓  &lt;strong&gt;加密模式&lt;/strong&gt;，也就是用  &lt;code&gt;公钥加密，私钥解密&lt;/code&gt;的模式。&lt;/p&gt; &lt;p&gt;加密模式的运行过程如下，A向B发消息X，已知B的公钥为KUbK_{Ub}KUb​，私钥为KRbK_{Rb}KRb​，加密算法为E，解密算法为D，则加密过程为Y=EKUb(X)Y=E_{K_{Ub}}(X)Y=EKUb​​(X)，解密过程X=DKRb(Y)X=D_{K_{Rb}}(Y)X=DKRb​​(Y)。之所以能够保证  &lt;strong&gt;传递消息是保密的&lt;/strong&gt;，是因为只有  &lt;code&gt;私钥才可以解密&lt;/code&gt;，而私钥只有B持有。所以所有想给B发消息的人，只需要用B的公钥和对应的加密算法对消息进行加密即可，而加密的消息只有B能解，保证了  &lt;strong&gt;消息的保密性&lt;/strong&gt;。&lt;/p&gt; &lt;h3&gt;  &lt;a href="https://luo41.top/#&amp;#35748;&amp;#35777;&amp;#27169;&amp;#24335;"&gt;&lt;/a&gt; 认证模式&lt;/h3&gt; &lt;p&gt;所谓  &lt;strong&gt;认证模式&lt;/strong&gt;，也就是用  &lt;code&gt;私钥加密，公钥解密&lt;/code&gt;的模式。&lt;/p&gt; &lt;p&gt;认证模式的运行过程如下，A向B发消息，已经A的公钥为KUaK_{Ua}KUa​，A的私钥为KRaK_{Ra}KRa​，加密算法为E，解密算法为D，则加密过程为Y=EKRa(X)Y=E_{K_{Ra}}(X)Y=EKRa​​(X)，解密过程为X=DKUa(Y)X=D_{K_{Ua}}(Y)X=DKUa​​(Y)，注意这里虽然说的是加密算法和解密算法，但是  &lt;strong&gt;认证模式&lt;/strong&gt;下并不能保证消息的保密性，因为只要知道A的公钥的人就可以解出明文，而公钥又是公开的，所以并不能提供消息的保密性，那么认证模式是来干嘛的呢？认证模式  &lt;strong&gt;只有私钥能加密&lt;/strong&gt;，借助这个  &lt;strong&gt;唯一加密&lt;/strong&gt;的特性，可以实现数字签名，私钥就相当于你的  &lt;strong&gt;字迹&lt;/strong&gt;，别人无法模仿的，别人一看到这个字迹就知道是你写的，就相当于别人用公钥验证私钥，验证成功，知道消息是你发的，提供了  &lt;strong&gt;认证性&lt;/strong&gt;。&lt;/p&gt; &lt;h3&gt;  &lt;a href="https://luo41.top/#&amp;#21516;&amp;#26102;&amp;#20855;&amp;#26377;&amp;#20445;&amp;#23494;&amp;#19982;&amp;#35748;&amp;#35777;&amp;#30340;&amp;#20844;&amp;#38053;&amp;#20307;&amp;#36136;"&gt;&lt;/a&gt; 同时具有保密与认证的公钥体质&lt;/h3&gt; &lt;p&gt;那么如果我们传送消息时，想要同时有  &lt;strong&gt;加密&lt;/strong&gt;和  &lt;strong&gt;认证&lt;/strong&gt;两种需求，如何做呢？很简单，就是用两对公私钥对，一对采用  &lt;strong&gt;加密模式&lt;/strong&gt;，一对才用  &lt;strong&gt;认证模式&lt;/strong&gt;。&lt;/p&gt; &lt;p&gt;假定A向B发消息，A的密钥对为{KUaK_{Ua}KUa​，KRaK_{Ra}KRa​}，B的密钥对为{KUbK_{Ub}KUb​，KRaK_{Ra}KRa​}，A要求发的消息同时具有  &lt;strong&gt;加密性&lt;/strong&gt;和  &lt;strong&gt;认证性&lt;/strong&gt;，怎么做呢？&lt;/p&gt; &lt;p&gt;首先是加密性，加密性需要用  &lt;code&gt;公钥加密，私钥解密&lt;/code&gt;，用谁的公钥呢？B的，因为B要查看消息，所以B要用自己的私钥去解密消息，所以A就用B的公钥去加密要传送的消息。  &lt;strong&gt;认证&lt;/strong&gt;需要用私钥加密，用谁的私钥呢？A的，因为B要确认消息是A所发出的，所以用A的私钥对消息进行加密，B收到消息后用解密算法进行验证，实现认证。&lt;/p&gt; &lt;p&gt;整个过程如下：假定发送的  &lt;strong&gt;明文为X&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;首先用B的公钥对消息进行加密Z=EKUb(X)Z=E_{K_{Ub}}(X)Z=EKUb​​(X)，这一步实现的是  &lt;strong&gt;加密&lt;/strong&gt;，然后再执行Y=EKRa(Z)Y=E_{K_{Ra}}(Z)Y=EKRa​​(Z)，这一步实现的是  &lt;strong&gt;认证&lt;/strong&gt;，然后将密文Y传送给B，B收到Y后首先做Z=DKUa(Y)Z=D_{K_{Ua}}(Y)Z=DKUa​​(Y)解出Z，然后执行X=DKRb(Z)X=D_{K_{Rb}}(Z)X=DKRb​​(Z)解出明文X，实现了  &lt;strong&gt;加密&lt;/strong&gt;和  &lt;strong&gt;认证&lt;/strong&gt;。&lt;/p&gt; &lt;h3&gt;  &lt;a href="https://luo41.top/#&amp;#20844;&amp;#38053;&amp;#23494;&amp;#30721;&amp;#20307;&amp;#21046;&amp;#24212;&amp;#28385;&amp;#36275;&amp;#30340;&amp;#35201;&amp;#27714;"&gt;&lt;/a&gt; 公钥密码体制应满足的要求&lt;/h3&gt; &lt;p&gt;公钥密文体制的运行也需要一些要求&lt;/p&gt; &lt;p&gt;  &lt;code&gt;一般要求：&lt;/code&gt;&lt;/p&gt; &lt;ol&gt;  &lt;li&gt;加密解密算法相同，但使用密钥不同&lt;/li&gt;  &lt;li&gt;发送方拥有加密或解密密钥，而接收方拥有另一个密钥。&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;  &lt;code&gt;安全性要求&lt;/code&gt;：&lt;/p&gt; &lt;ol&gt;  &lt;li&gt;两个密钥之一必须保密，   &lt;strong&gt;作为私钥&lt;/strong&gt;&lt;/li&gt;  &lt;li&gt;无解密密钥，解密不可行&lt;/li&gt;  &lt;li&gt;知道算法和其中一个密钥，以及若干个密文不能确定另一个密文。&lt;/li&gt;&lt;/ol&gt; &lt;h3&gt;  &lt;a href="https://luo41.top/#&amp;#20851;&amp;#20110;&amp;#20844;&amp;#38053;&amp;#23494;&amp;#30721;&amp;#30340;&amp;#20960;&amp;#31181;&amp;#35823;&amp;#35299;"&gt;&lt;/a&gt; 关于公钥密码的几种误解&lt;/h3&gt; &lt;ol&gt;  &lt;li&gt;   &lt;p&gt;公钥密码比传统密码更安全？&lt;/p&gt;   &lt;p&gt;任何加密算法的    &lt;strong&gt;安全性&lt;/strong&gt;依赖于    &lt;strong&gt;密钥的长度&lt;/strong&gt;和    &lt;strong&gt;破译密文所需要的计算量&lt;/strong&gt;。从抗密码分析的角度来看，原则上不能说传统密码优于公钥密码，而不能说公钥密码优于传统密码。&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;公钥密码是通用方法，所以传统密码已经过时？&lt;/p&gt;   &lt;p&gt;其实恰恰相反，由于现有的公钥密码方法所需的    &lt;strong&gt;计算量大&lt;/strong&gt;，取缔传统密码似乎不太可能，仅限用在    &lt;strong&gt;密钥管理&lt;/strong&gt;和    &lt;strong&gt;签名&lt;/strong&gt;这类应用上。&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;公钥密码实现密钥分配非常简单？&lt;/p&gt;   &lt;p&gt;事实上，使用公钥密码也需要某种形式的    &lt;strong&gt;协议&lt;/strong&gt;，该协议通常包含一个    &lt;strong&gt;中心代理&lt;/strong&gt;，并且它的处理过程也不比传统密码中的那些过程简单和有效。&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt; &lt;h2&gt;  &lt;a href="https://luo41.top/#rsa"&gt;&lt;/a&gt; RSA&lt;/h2&gt; &lt;p&gt;RSA公开密钥密码体制是最著名且被广泛使用的公开密钥密码体制。&lt;/p&gt; &lt;h3&gt;  &lt;a href="https://luo41.top/#rsa&amp;#31639;&amp;#27861;&amp;#30340;&amp;#22522;&amp;#26412;&amp;#36807;&amp;#31243;"&gt;&lt;/a&gt; RSA算法的基本过程&lt;/h3&gt; &lt;p&gt;首先，明文和密文是0~n-1之间的整数，通常n的大小为1024位或309位十进制。&lt;/p&gt; &lt;p&gt;  &lt;code&gt;RSA算法描述&lt;/code&gt;&lt;/p&gt; &lt;p&gt;  &lt;strong&gt;加密&lt;/strong&gt;：C=Me mod NC=M^{e} \ mod \ NC=Me mod N  where 0&amp;lt;= M &amp;lt; N&lt;/p&gt; &lt;p&gt;  &lt;strong&gt;解密&lt;/strong&gt;：$M=C^{d} mod \ N \ $&lt;/p&gt; &lt;p&gt;公钥为(e,N)，私钥为(d,N)。&lt;/p&gt; &lt;p&gt;必须满足的以下条件&lt;/p&gt; &lt;ol&gt;  &lt;li&gt;   &lt;p&gt;Med≡M mod NM^{ed} ≡ M \ mod \ NMed≡M mod N&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;计算MeM^{e}Me和CdC^{d}Cd是比较容易的(    &lt;strong&gt;效率&lt;/strong&gt;)。&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;由e和n确定d是不可行的(    &lt;strong&gt;安全&lt;/strong&gt;)。&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt; &lt;h3&gt;  &lt;a href="https://luo41.top/#&amp;#23494;&amp;#38053;&amp;#20135;&amp;#29983;&amp;#36807;&amp;#31243;"&gt;&lt;/a&gt; 密钥产生过程&lt;/h3&gt; &lt;ol&gt;  &lt;li&gt;   &lt;p&gt;随机选择两个不等的    &lt;strong&gt;大素数&lt;/strong&gt;p，q&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;计算N=p*q，对应有ϕ(N)=(p−1)×(q−1)\phi(N)=(p-1)×(q-1)ϕ(N)=(p−1)×(q−1)&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;选择e使得 1&amp;lt;e&amp;lt;ϕ(N)1&amp;lt;e&amp;lt;\phi(N)1&amp;lt;e&amp;lt;ϕ(N)，且$gcd(e,\phi(N)) = 1 （使得e在（使得e在（使得e在\phi(N)$下存在    &lt;strong&gt;逆元&lt;/strong&gt;，也就是后面我们要求的d）&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;解下列方程求出d&lt;/p&gt;   &lt;p&gt;ed≡1 mod ϕ(N)ed ≡ 1 \ mod \ \phi(N)ed≡1 mod ϕ(N)  且 0&amp;lt;= d &amp;lt;= N&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;公布公钥KU={e，N}&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;保存私钥KR={d，N}&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt; &lt;h3&gt;  &lt;a href="https://luo41.top/#rsa&amp;#30340;&amp;#20351;&amp;#29992;"&gt;&lt;/a&gt; RSA的使用&lt;/h3&gt; &lt;ol&gt;  &lt;li&gt;发送方加密明文M   &lt;ul&gt;    &lt;li&gt;获取接收方的公钥KU={e,N}&lt;/li&gt;    &lt;li&gt;计算$C=M^{e} \ mod \ N $  where 0&amp;lt;= M &amp;lt; N&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;  &lt;li&gt;接收方解密密文C   &lt;br /&gt;用自己的私钥KR={d，N}，计算 M=Cd mod NM=C^{d} \ mod \ NM=Cd mod N&lt;/li&gt;&lt;/ol&gt; &lt;h3&gt;  &lt;a href="https://luo41.top/#&amp;#20026;&amp;#20160;&amp;#20040;rsa&amp;#21487;&amp;#20197;&amp;#21152;&amp;#35299;&amp;#23494;"&gt;&lt;/a&gt; 为什么RSA可以加解密？&lt;/h3&gt; &lt;p&gt;由  &lt;strong&gt;欧拉定理&lt;/strong&gt;：&lt;/p&gt; &lt;blockquote&gt;  &lt;p&gt;欧拉定理：设n和a为正整数，且gcd(a,n) = 1，则 aϕ(n)≡1 (mod n)a^{\phi(n)} ≡ 1\ (mod \ n)aϕ(n)≡1 (mod n)&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;又在RSA ：ed≡1 mod ϕ(N)ed ≡ 1 \ mod \ \phi(N)ed≡1 mod ϕ(N)，等价于ed=kϕ(N)+1ed=k\phi(N)+1ed=kϕ(N)+1&lt;/p&gt; &lt;p&gt;所以$M^{ed} ≡ M \ mod \ N $&lt;/p&gt; &lt;p&gt;等价于 Mkϕ(N)+1≡M mod NM^{k\phi(N)+1} ≡ M \ mod \ NMkϕ(N)+1≡M mod N&lt;/p&gt; &lt;p&gt;在RSA中 N=p×q，p,q为素数，所以有ϕ(N)=(p−1)×(q−1)\phi(N)=(p-1)×(q-1)ϕ(N)=(p−1)×(q−1)&lt;/p&gt; &lt;p&gt;且 ed≡1 mod ϕ(N)ed ≡ 1 \ mod \ \phi(N)ed≡1 mod ϕ(N)&lt;/p&gt; &lt;p&gt;因此，有Cd≡(Me)d=Med≡M mod N=MC^{d}≡ (M^{e})^{d}=M^{ed} ≡ M \ mod \ N = MCd≡(Me)d=Med≡M mod N=M&lt;/p&gt; &lt;h3&gt;  &lt;a href="https://luo41.top/#rsa&amp;#23494;&amp;#38053;key&amp;#30340;&amp;#36873;&amp;#25321;"&gt;&lt;/a&gt; RSA密钥key的选择&lt;/h3&gt; &lt;p&gt;从安全性考虑，key的选择需要以下规则&lt;/p&gt; &lt;ol&gt;  &lt;li&gt;p和q不能太接近&lt;/li&gt;  &lt;li&gt;p-1 和 q-1必须包含大的素因子&lt;/li&gt;  &lt;li&gt;gcd(q-1,p-1)必须小&lt;/li&gt;  &lt;li&gt;e和d不能太小，e可选65537&lt;/li&gt;  &lt;li&gt;d不能小于n1/4n^{1/4}n1/4&lt;/li&gt;&lt;/ol&gt; &lt;h3&gt;  &lt;a href="https://luo41.top/#rsa&amp;#30340;&amp;#23433;&amp;#20840;&amp;#24615;"&gt;&lt;/a&gt; RSA的安全性&lt;/h3&gt; &lt;ul&gt;  &lt;li&gt;   &lt;p&gt;强力穷举攻击：    &lt;strong&gt;穷举&lt;/strong&gt;所有可能的私钥&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;数学攻击：实质是对两个素数的乘积N的分解，由N求得ϕ(N)\phi(N)ϕ(N)是困难的，因此要将N分解为p和q两个质数，然后利用ϕ(N)=(p−1)∗(q−1)\phi(N)=(p-1)*(q-1)ϕ(N)=(p−1)∗(q−1)&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;时间攻击 ：不懂&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;    &lt;strong&gt;选择密文攻击CCA&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;三种数学攻击方法&lt;/p&gt; &lt;ol&gt;  &lt;li&gt;   &lt;p&gt;分解N=p*q，由此可算出ϕ(N)\phi(N)ϕ(N)，从而确定d&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;直接确定ϕ(N)\phi(N)ϕ(N)，然后找到d&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;直接确定d&lt;/p&gt;   &lt;p&gt;本质上都是要找到ϕ(N)\phi(N)ϕ(N)或直接找到d，由    &lt;code&gt;N确定$\phi(N)$可等价于因子分解&lt;/code&gt;。&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt; &lt;h3&gt;  &lt;a href="https://luo41.top/#rsa&amp;#20844;&amp;#38053;&amp;#20307;&amp;#36136;&amp;#30340;&amp;#23433;&amp;#20840;&amp;#24615;&amp;#26159;&amp;#24314;&amp;#31435;&amp;#22312;&amp;#21738;&amp;#31181;&amp;#20107;&amp;#23454;&amp;#20043;&amp;#19978;"&gt;&lt;/a&gt; RSA公钥体质的安全性是建立在哪种事实之上？&lt;/h3&gt; &lt;p&gt;  &lt;strong&gt;因子分解&lt;/strong&gt;具有大素数因子的数仍然是一个难题。&lt;/p&gt; &lt;h3&gt;  &lt;a href="https://luo41.top/#&amp;#36873;&amp;#25321;&amp;#23494;&amp;#25991;cca"&gt;&lt;/a&gt; 选择密文CCA&lt;/h3&gt; &lt;p&gt;选择密文攻击是假定攻击者有一台  &lt;strong&gt;解密机&lt;/strong&gt;，除了待解的密文，攻击者可以输入任意的密文，然后解密机就会给出对应的明文，因此攻击者可以构造特殊的密文，去求解出  &lt;strong&gt;待解的密文&lt;/strong&gt;。&lt;/p&gt; &lt;p&gt;给定待解密文C∗C^{*}C∗，求对应的明文M∗M^{*}M∗，并给出一个解密机O&lt;/p&gt; &lt;p&gt;  &lt;strong&gt;攻击过程&lt;/strong&gt;：&lt;/p&gt; &lt;p&gt;构造密文C=2eC∗C=2^{e}C^{*}C=2eC∗&lt;/p&gt; &lt;p&gt;将C输入到解密机O，得到对应的明文M&lt;/p&gt; &lt;p&gt;M=(Cd mod N)=(2eC∗)d mod N=2edC∗d mod N=2∗m∗ mod N=2m∗M=(C^{d} \ mod \ N)=(2^{e}C^{*})^{d} \ mod \ N = 2^{ed}C^{*d} \ mod \ N = 2* m^{*} \ mod \ N = 2m^{*}M=(Cd mod N)=(2eC∗)d mod N=2edC∗d mod N=2∗m∗ mod N=2m∗&lt;/p&gt; &lt;p&gt;于是便可以求得m∗m^{*}m∗&lt;/p&gt; &lt;h2&gt;  &lt;a href="https://luo41.top/#diffie-hellman-&amp;#23494;&amp;#38053;&amp;#20132;&amp;#25442;&amp;#21327;&amp;#35758;"&gt;&lt;/a&gt; Diffie-Hellman 密钥交换协议&lt;/h2&gt; &lt;p&gt;Diffie-Hellman需要原根(生成元)的定义&lt;/p&gt; &lt;p&gt;  &lt;code&gt;原根&lt;/code&gt;：如果a是素数p的原根，则数 a mod p,a2 mod pa^{2} \ mod \ pa2 mod p … ap−1 mod pa^{p-1} \ mod \ pap−1 mod p是不同的并且包含1到p-1的整数的  &lt;strong&gt;某种排列&lt;/strong&gt;。原根是数论的概念。&lt;/p&gt; &lt;p&gt;  &lt;code&gt;生成元&lt;/code&gt;：p为素数，g是Zp∗Z_{p}^{*}Zp∗​的生成元，当且仅当g的阶是p-1. 生成元是  &lt;strong&gt;群论的概念&lt;/strong&gt;。&lt;/p&gt; &lt;p&gt;Diffie-Hellman公钥体制&lt;/p&gt; &lt;p&gt;目标：Alice和Bob试图在公开网络上通过交互建立一个  &lt;strong&gt;秘密&lt;/strong&gt;&lt;/p&gt; &lt;h3&gt;  &lt;a href="https://luo41.top/#diffie-hellman-&amp;#23494;&amp;#38053;&amp;#20132;&amp;#25442;&amp;#31639;&amp;#27861;"&gt;&lt;/a&gt; Diffie-Hellman 密钥交换算法&lt;/h3&gt; &lt;p&gt;  &lt;code&gt;全局公开量：&lt;/code&gt;&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;大素数：p&lt;/li&gt;  &lt;li&gt;选g为Zp∗Z_{p}^{*}Zp∗​的生成元&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;  &lt;code&gt;Alice密钥的产生&lt;/code&gt;：&lt;/p&gt; &lt;p&gt;选择随机数x&amp;lt;p&lt;/p&gt; &lt;p&gt;计算公开量 X=gx mod pX=g^{x} \ mod \ pX=gx mod p&lt;/p&gt; &lt;p&gt;  &lt;code&gt;Bob密钥的产生&lt;/code&gt;：&lt;/p&gt; &lt;p&gt;选择随机数y&amp;lt;p&lt;/p&gt; &lt;p&gt;计算公开量Y=gy mod pY=g^{y}\ mod \ pY=gy mod p&lt;/p&gt; &lt;p&gt;  &lt;code&gt;协议过程&lt;/code&gt;：&lt;/p&gt; &lt;p&gt;Alice -----&amp;gt; Bob:X&lt;/p&gt; &lt;p&gt;Bob -------&amp;gt; Alice：Y&lt;/p&gt; &lt;p&gt;  &lt;code&gt;产生密钥&lt;/code&gt;：&lt;/p&gt; &lt;p&gt;Alice接受到了Y，计算KAB=Yx mod qK_{AB}=Y^{x} \ mod \ qKAB​=Yx mod q&lt;/p&gt; &lt;p&gt;Bob接受到了X，计算KAB=Xy mod qK_{AB}=X^{y}\ mod \ qKAB​=Xy mod q&lt;/p&gt; &lt;p&gt;KAB=gxy mod qK_{AB}=g^{xy}\ mod \ qKAB​=gxy mod q&lt;/p&gt; &lt;p&gt;这样双方就都计算出了密钥KABK_{AB}KAB​，成功完成了密钥的交换，且  &lt;strong&gt;各自的私钥x和y没有暴露&lt;/strong&gt;。&lt;/p&gt; &lt;p&gt;为什么没有暴露呢？因为传递的是X和Y，而Diffie-Hellman密钥的安全性正是建立在如下的事实上：  &lt;code&gt;求关于素数的模幂运算相对容易，而计算离散对数问题却非常困难，对于大素数，求离散对数问题被认为是计算上不可行的&lt;/code&gt;&lt;/p&gt; &lt;blockquote&gt;  &lt;p&gt;离散对数问题：给定y=gx mod py=g^{x} \ mod \ py=gx mod p，知道y,g,p，求x在计算上是不可行的，如果p是一个大素数&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;正因如此，双方才能在各自私钥不暴露的情况下完成密钥(KABK_{AB}KAB​)的交换。&lt;/p&gt; &lt;h3&gt;  &lt;a href="https://luo41.top/#diffie-hellman&amp;#31639;&amp;#27861;&amp;#20013;&amp;#23384;&amp;#22312;&amp;#30340;&amp;#38382;&amp;#39064;"&gt;&lt;/a&gt; Diffie-Hellman算法中存在的问题&lt;/h3&gt; &lt;p&gt;Diffie-Hellman算法中存在的问题就是  &lt;strong&gt;不能对抗中间人攻击&lt;/strong&gt;。&lt;/p&gt; &lt;p&gt;  &lt;code&gt;中间人攻击原理如下&lt;/code&gt;：&lt;/p&gt; &lt;img src="https://luo41.top/2022/01/20/ComSec%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%AE%89%E5%85%A8OverView/1.png"&gt;&lt;/img&gt; &lt;p&gt;那么如何对抗中间人攻击呢？之所以存在中间人攻击，是因为Diffie-Hellman没有对通信的参与方  &lt;strong&gt;进行认证&lt;/strong&gt;，所以引入  &lt;strong&gt;认证&lt;/strong&gt;机制可以抵抗中间人攻击，如何引入  &lt;strong&gt;认证机制&lt;/strong&gt;？就要用到我们前面提到的公钥密码的认证模式，具体的应用为  &lt;strong&gt;数字签名&lt;/strong&gt;，通过添加  &lt;strong&gt;数字签名&lt;/strong&gt;对通信的参与方进行认证，从而对抗中间人攻击。&lt;/p&gt; &lt;h2&gt;  &lt;a href="https://luo41.top/#ecc&amp;#26925;&amp;#22278;&amp;#35745;&amp;#31639;"&gt;&lt;/a&gt; ECC椭圆计算&lt;/h2&gt; &lt;p&gt;只是一个只会在ZpZ_{p}Zp​上计算的做题家罢了。&lt;/p&gt; &lt;h2&gt;  &lt;a href="https://luo41.top/#hash&amp;#19982;mac&amp;#37096;&amp;#20998;"&gt;&lt;/a&gt; Hash与MAC部分&lt;/h2&gt; &lt;p&gt;  &lt;code&gt;Hash函数&lt;/code&gt;：Hash函数不是加密解密函数，只是  &lt;strong&gt;保证消息的完整性&lt;/strong&gt;，在密码学中具有重要的理论和应用价值。&lt;/p&gt; &lt;p&gt;  &lt;code&gt;Hash函数的定义&lt;/code&gt;&lt;/p&gt; &lt;ol&gt;  &lt;li&gt;Hash函数是将   &lt;strong&gt;任意长度&lt;/strong&gt;的报文   &lt;strong&gt;映射&lt;/strong&gt;成一个   &lt;strong&gt;较短的定长&lt;/strong&gt;输出报文的函数。&lt;/li&gt;  &lt;li&gt;如下形式 h=H(M)，M是边长的报文，h是定长的Hash值。&lt;/li&gt;  &lt;li&gt;Hash函数的目的是为文件，报文或其他的分组数据产生   &lt;strong&gt;数字指纹&lt;/strong&gt;，通过检查“数字指纹”判断消息有没有被篡改过，从而判断   &lt;strong&gt;消息的完整性&lt;/strong&gt;。&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;  &lt;code&gt;对Hash函数的要求：&lt;/code&gt;&lt;/p&gt; &lt;ol&gt;  &lt;li&gt;能用于任何大小的数据分组&lt;/li&gt;  &lt;li&gt;H产生定长输出&lt;/li&gt;  &lt;li&gt;对任意给定的x，H(x)要相对   &lt;strong&gt;易于计算&lt;/strong&gt;，使得软硬件实现都变得可行。&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;  &lt;code&gt;安全性需求&lt;/code&gt;：&lt;/p&gt; &lt;ol&gt;  &lt;li&gt;   &lt;p&gt;    &lt;strong&gt;单向性&lt;/strong&gt;：对任意给定的码y，寻求x使得H(x)=y     &lt;strong&gt;在计算上不可行&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;    &lt;strong&gt;弱抗碰撞性&lt;/strong&gt;：任意分组x，寻求不等于x的x’，使得H(x)=H(x’)    &lt;strong&gt;在计算上不可行&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;    &lt;strong&gt;强抗碰撞性&lt;/strong&gt;：寻求任何的(x，x’)，使得H(x)=H(x’)    &lt;strong&gt;在计算上不可行&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;  &lt;code&gt;密码学Hash函数的应用&lt;/code&gt;&lt;/p&gt; &lt;ol&gt;  &lt;li&gt;   &lt;p&gt;    &lt;strong&gt;消息认证&lt;/strong&gt;：验证消息    &lt;strong&gt;完整性&lt;/strong&gt;的一种机制或服务。确保收到的数据确实和发送时一样，即没有发生第三方截获了消息，进行修改，插入，删除或重放。此外，通常还要求消息认证机制确保&amp;quot;    &lt;strong&gt;发送方声称的身份是真实有效的&lt;/strong&gt;&amp;quot;，Hash函数用于提供消息认证功能时，Hash值也称为    &lt;strong&gt;消息摘要&lt;/strong&gt;。更一般地，消息认证是通过    &lt;strong&gt;消息认证码MAC&lt;/strong&gt;实现的，MAC即    &lt;strong&gt;带密钥&lt;/strong&gt;的Hash。通信双方基于    &lt;strong&gt;共享的同一密钥&lt;/strong&gt;来认证彼此交互的消息，就会使用MAC。&lt;/p&gt;   &lt;p&gt;总体来看 MAC是    &lt;strong&gt;Hash函数和加密函数的集合&lt;/strong&gt;,对Hash值保密，防止中间人篡改后轻松地    &lt;strong&gt;伪造Hash值&lt;/strong&gt;。&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;    &lt;strong&gt;数字签名&lt;/strong&gt;：&lt;/p&gt;   &lt;p&gt;Hash函数另一个重要的应用是    &lt;strong&gt;数字签名&lt;/strong&gt;。数字签名的操作与MAC相似，但MAC防止是第三方的截获和篡改，而数字签名防止的是通信双方自己之间的欺骗(    &lt;strong&gt;…全得防着，太可怕了&lt;/strong&gt;)。在进行数字签名的过程中，使用用户的    &lt;strong&gt;私钥&lt;/strong&gt;加密消息的Hash值，其他任何知道该用户    &lt;strong&gt;公钥&lt;/strong&gt;的人都能够通过数字签名来    &lt;strong&gt;验证消息的完整性&lt;/strong&gt;。&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt; &lt;h2&gt;  &lt;a href="https://luo41.top/#&amp;#35748;&amp;#35777;&amp;#25216;&amp;#26415;"&gt;&lt;/a&gt; 认证技术&lt;/h2&gt; &lt;p&gt;认证是防止  &lt;strong&gt;主动攻击&lt;/strong&gt;的重要技术，对开放系统的安全性起到重要作用。&lt;/p&gt; &lt;p&gt;认证的主要目的是：&lt;/p&gt; &lt;p&gt;一   &lt;strong&gt;实体认证&lt;/strong&gt;(  &lt;strong&gt;发送者非冒充&lt;/strong&gt;)&lt;/p&gt; &lt;p&gt;二   &lt;strong&gt;报文认证&lt;/strong&gt;(验证消息的完整性)&lt;/p&gt; &lt;h3&gt;  &lt;a href="https://luo41.top/#&amp;#25253;&amp;#25991;&amp;#35748;&amp;#35777;mac"&gt;&lt;/a&gt; 报文认证MAC&lt;/h3&gt; &lt;p&gt;报文认证，简单而言，就是要求接收方可以确保发送方发来的数据具有  &lt;strong&gt;真实性&lt;/strong&gt;，没有被篡改或是伪造数据。&lt;/p&gt; &lt;p&gt;  &lt;code&gt;报文认证实例&lt;/code&gt;&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;在电子商务系统中，在电子政务系统中，我们需要确认某些电子文档不是伪造的。&lt;/li&gt;  &lt;li&gt;在实际应用中，我们考虑如何把非法软件与合法软件区分开来。&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;  &lt;code&gt;特点&lt;/code&gt;：第三方可仲裁，离线或者非实时。&lt;/p&gt; &lt;h3&gt;  &lt;a href="https://luo41.top/#&amp;#23454;&amp;#20307;&amp;#35748;&amp;#35777;-&amp;#29992;&amp;#25143;&amp;#35748;&amp;#35777;"&gt;&lt;/a&gt; 实体认证 – 用户认证&lt;/h3&gt; &lt;ul&gt;  &lt;li&gt;确保正在参与通信者是一个非冒充用户，比如QQ,MSN等即时通信系统，邮件系统等&lt;/li&gt;  &lt;li&gt;实例：安全登录&lt;/li&gt;  &lt;li&gt;特性：实时，在线，多方参与…&lt;/li&gt;&lt;/ul&gt; &lt;h3&gt;  &lt;a href="https://luo41.top/#&amp;#25253;&amp;#25991;&amp;#35748;&amp;#35777;"&gt;&lt;/a&gt; 报文认证&lt;/h3&gt; &lt;p&gt;Ailice与Bob共同拥有一个秘密sk，Alice用sk加密M给Bob，Bob解密，立即可知此报文是真假是假。但是这种方法无法防止Alice和Bob之间的相互欺骗，例如Alice否认自己发送过消息，因为Bob也可以伪造Alice给自己发消息，同时Bob也可以否认自己收过某条消息，问题的症状在于Alice与Bob共同拥有  &lt;strong&gt;私钥sk&lt;/strong&gt;,而后的数字签名就是来解决这个问题的。&lt;/p&gt; &lt;h3&gt;  &lt;a href="https://luo41.top/#mac&amp;#30340;&amp;#23433;&amp;#20840;&amp;#24615;&amp;#38656;&amp;#27714;"&gt;&lt;/a&gt; MAC的安全性需求&lt;/h3&gt; &lt;ul&gt;  &lt;li&gt;某个报文M的   &lt;strong&gt;MAC&lt;/strong&gt;必须要短小&lt;/li&gt;  &lt;li&gt;要有   &lt;strong&gt;认证性&lt;/strong&gt;，发送接收双方必须共享   &lt;strong&gt;秘密&lt;/strong&gt;，看了有些博客，好像也叫   &lt;strong&gt;初始信任&lt;/strong&gt;，有了初始信任才能有认证。&lt;/li&gt;  &lt;li&gt;Hash不足以保证安全&lt;/li&gt;  &lt;li&gt;避免“加密运算”&lt;/li&gt;&lt;/ul&gt; &lt;h2&gt;  &lt;a href="https://luo41.top/#&amp;#25968;&amp;#23383;&amp;#31614;&amp;#21517;"&gt;&lt;/a&gt; 数字签名&lt;/h2&gt; &lt;p&gt;签名提到了MAC报文认证，MAC理论的遗留问题：要求通信双方首先要共享  &lt;strong&gt;秘密&lt;/strong&gt;，也称为初始信任，之后才能有认证，双方共享sk，似乎是个很强的要求，但有了  &lt;strong&gt;公钥密码体制&lt;/strong&gt;(PKC)，这个问题可以得到解决。&lt;/p&gt; &lt;p&gt;  &lt;code&gt;数字签名是认证的重要工具&lt;/code&gt;。&lt;/p&gt; &lt;p&gt;  &lt;code&gt;为什么需要数字签名&lt;/code&gt;：&lt;/p&gt; &lt;p&gt;前面提到了报文认证是用来保护双方之间的数据交换不被第三方侵扰，但它并不能保证  &lt;strong&gt;双方自身的相互欺骗&lt;/strong&gt;。&lt;/p&gt; &lt;p&gt;实例：&lt;/p&gt; &lt;p&gt;假定A发送一个认证的信息给B，双方之间的争议可能有：&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;B伪造一个不同的消息(   &lt;strong&gt;因为B也有sk&lt;/strong&gt;)，但声称是从A收到的&lt;/li&gt;  &lt;li&gt;A可以否认发过该消息(   &lt;strong&gt;因为A可以说是B自己给自己发的&lt;/strong&gt;)，B无法证明A确实发了该消息&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;问题的症状在于双方都有  &lt;strong&gt;sk&lt;/strong&gt;，都可以进行发消息和验证消息，问题在于发送和验证职责的分离。&lt;/p&gt; &lt;p&gt;  &lt;code&gt;数字签名的直观定义&lt;/code&gt;：&lt;/p&gt; &lt;p&gt;  &lt;strong&gt;目标&lt;/strong&gt;：防止报文被伪造，用于保证数据的完整性&lt;/p&gt; &lt;p&gt;  &lt;strong&gt;操作&lt;/strong&gt;：签名者对报文产生一串  &lt;strong&gt;公开且他人无法伪造的数据串&lt;/strong&gt;，公开是为了给他人验证，无法伪造是保证发送方无法否认发过该消息。&lt;/p&gt; &lt;p&gt;方法：PKC+Hash  PKC用私钥加密，公钥解密，提供认证性，Hash提供消息的完整性。&lt;/p&gt; &lt;h4&gt;  &lt;a href="https://luo41.top/#&amp;#25968;&amp;#23383;&amp;#31614;&amp;#21517;&amp;#24212;&amp;#20855;&amp;#26377;&amp;#30340;&amp;#24615;&amp;#36136;"&gt;&lt;/a&gt; 数字签名应具有的性质&lt;/h4&gt; &lt;ul&gt;  &lt;li&gt;必须能够验证签名者以及签名的日期，时间等&lt;/li&gt;  &lt;li&gt;必须能够认证签名的报文内容&lt;/li&gt;  &lt;li&gt;签名能够由第三方验证，以解决收发双发的争议&lt;/li&gt;&lt;/ul&gt; &lt;h2&gt;  &lt;a href="https://luo41.top/#&amp;#35748;&amp;#35777;&amp;#31995;&amp;#32479;"&gt;&lt;/a&gt; 认证系统&lt;/h2&gt; &lt;h3&gt;  &lt;a href="https://luo41.top/#&amp;#35777;&amp;#20070;"&gt;&lt;/a&gt; 证书&lt;/h3&gt; &lt;p&gt;  &lt;code&gt;证书的定义：&lt;/code&gt; 公钥 &amp;lt;------&amp;gt; 用户&lt;/p&gt; &lt;p&gt;通俗将：数字证书就是把  &lt;code&gt;公钥与其所有者的身份&lt;/code&gt;进行  &lt;strong&gt;绑定&lt;/strong&gt;的文档。&lt;/p&gt; &lt;p&gt;而绑定的方法就是：  &lt;code&gt;权威机构(证书颁布机构)CA的数字签名&lt;/code&gt;。&lt;/p&gt; &lt;p&gt;  &lt;code&gt;两个实体&lt;/code&gt;：&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;证书用户：使用证书的实体&lt;/li&gt;  &lt;li&gt;证书所有者：证书中的主体，证书中公钥的持有者&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;  &lt;code&gt;证书的格式&lt;/code&gt;&lt;/p&gt; &lt;ol&gt;  &lt;li&gt;   &lt;p&gt;    &lt;strong&gt;版本号&lt;/strong&gt; Version：区分证书的不同版本&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;    &lt;strong&gt;证书序列号&lt;/strong&gt; Serial number 一个证书，在CA中    &lt;strong&gt;唯一标识证书&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;    &lt;strong&gt;签名算法标识&lt;/strong&gt;：带参数的，用于给证书签名的算法&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;    &lt;strong&gt;发行商名字&lt;/strong&gt; Issuer name 创建签名证书的签证机构CA的名字&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;    &lt;strong&gt;有效期&lt;/strong&gt; 生效日期和终止日期&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;    &lt;strong&gt;证书主体名&lt;/strong&gt; 获得证书的用户名，证明拥有相应密钥的主体是公钥的所有者&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;    &lt;strong&gt;发行商唯一标识&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;    &lt;strong&gt;证书主体唯一标识&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;…    &lt;strong&gt;拓展&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;    &lt;strong&gt;签名&lt;/strong&gt;：用CA私钥对证书的    &lt;strong&gt;所有域&lt;/strong&gt;及这些域的Hash的值一起加密(    &lt;strong&gt;用私钥&lt;/strong&gt;)&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt; &lt;h3&gt;  &lt;a href="https://luo41.top/#pki-public-key-infrastructure-&amp;#20844;&amp;#38053;&amp;#22522;&amp;#30784;&amp;#35774;&amp;#26045;"&gt;&lt;/a&gt;   &lt;code&gt;PKI Public Key Infrastructure&lt;/code&gt; 公钥基础设施&lt;/h3&gt; &lt;p&gt;用来提供可靠易用的  &lt;strong&gt;公钥密码&lt;/strong&gt;操作的  &lt;strong&gt;系统的总称&lt;/strong&gt;。&lt;/p&gt; &lt;p&gt;主要目标：保障大型开放式网络环境下的网络和信息安全&lt;/p&gt; &lt;p&gt;  &lt;code&gt;PKI系统的主要组成&lt;/code&gt;：&lt;/p&gt; &lt;p&gt;  &lt;img alt="image-20220120144003640" src="https://luo41.top/2022/01/20/ComSec%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%AE%89%E5%85%A8OverView/C:%5CUsers%5CLenovo%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5Cimage-20220120144003640.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;p&gt;  &lt;code&gt;PKI系统主要组成&lt;/code&gt;：&lt;/p&gt; &lt;ol&gt;  &lt;li&gt;   &lt;strong&gt;PKI策略&lt;/strong&gt; 定义和建立了一个组织信息安全方面的指导方针，同时也定义了密码系统使用的处理方法和原则&lt;/li&gt;  &lt;li&gt;   &lt;strong&gt;认证机构CA(Certificate Authority)系统&lt;/strong&gt;   &lt;br /&gt;PKI的信任基础，它管理了   &lt;strong&gt;公钥的整个生命周期&lt;/strong&gt;，其作用包括：审计用户身份的RA，发放证书，规定证书的有效期和通过发布证书废除列表确保必要时可以废除证书。&lt;/li&gt;  &lt;li&gt;   &lt;strong&gt;PKI应用&lt;/strong&gt;   &lt;br /&gt;为各种应用提供访问PKI的方式&lt;/li&gt;&lt;/ol&gt; &lt;h4&gt;  &lt;a href="https://luo41.top/#&amp;#35748;&amp;#35777;&amp;#26426;&amp;#26500;ca&amp;#31995;&amp;#32479;"&gt;&lt;/a&gt; 认证机构CA系统&lt;/h4&gt; &lt;p&gt;PKI的  &lt;strong&gt;核心是认证机构CA系统&lt;/strong&gt;。&lt;/p&gt; &lt;p&gt;CA系统：&lt;/p&gt; &lt;ol&gt;  &lt;li&gt;权威的，可信任的，公正的第三方机构&lt;/li&gt;  &lt;li&gt;   &lt;strong&gt;认证中心&lt;/strong&gt;&lt;/li&gt;  &lt;li&gt;   &lt;strong&gt;PKI的核心&lt;/strong&gt;&lt;/li&gt;  &lt;li&gt;数字证书的   &lt;strong&gt;签发机构&lt;/strong&gt;&lt;/li&gt;  &lt;li&gt;负责证书的产生，存档，发放，查询，恢复以及作废管理&lt;/li&gt;  &lt;li&gt;一个典型的CA系统包括安全服务器，   &lt;strong&gt;注册机构RA&lt;/strong&gt;，CA服务器，LDAP目录服务器和数据库服务器等。&lt;/li&gt;&lt;/ol&gt; &lt;img src="https://luo41.top/2022/01/20/ComSec%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%AE%89%E5%85%A8OverView/2.png"&gt;&lt;/img&gt; &lt;p&gt;  &lt;code&gt;注册机构RA&lt;/code&gt;：&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;   &lt;p&gt;RA是数字证书    &lt;strong&gt;注册审批&lt;/strong&gt;机构&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;RA提供用户和CA之间的一个接口，它获取并认证用户的身份，向CA    &lt;strong&gt;提出证书请求&lt;/strong&gt;，它主要完成    &lt;strong&gt;收集用户信息&lt;/strong&gt;和    &lt;strong&gt;确认用户身份的&lt;/strong&gt;功能&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;它接受用户的注册申请，审查用户的申请资格，并决定是否同意CA给其签发数字证书。&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;注：    &lt;code&gt;注册机构并不给用户签发证书&lt;/code&gt;，而只是对用户进行资格审查。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;  &lt;code&gt;CA的任务&lt;/code&gt;：&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;验证并标识证书申请者的身份&lt;/li&gt;  &lt;li&gt;   &lt;strong&gt;签发证书&lt;/strong&gt;&lt;/li&gt;  &lt;li&gt;证书资料信息的管理(   &lt;strong&gt;公钥证书序列号，CA标识&lt;/strong&gt;)&lt;/li&gt;  &lt;li&gt;   &lt;strong&gt;产生和发布撤销&lt;/strong&gt;证书列表&lt;/li&gt;  &lt;li&gt;证书的归档&lt;/li&gt;  &lt;li&gt;密钥归档与恢复&lt;/li&gt;  &lt;li&gt;历史数据归档&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;  &lt;code&gt;CA的职责&lt;/code&gt;：&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;确保CA用于签名证书的非对称密钥的质量&lt;/li&gt;  &lt;li&gt;确保整个签证过程的安全性，   &lt;strong&gt;确保签名私钥的安全性&lt;/strong&gt;&lt;/li&gt;  &lt;li&gt;确保证书主体标识的唯一性，防止重名&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;  &lt;code&gt;CA的密钥&lt;/code&gt;：&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;是整个证书机制得以运行的基础&lt;/li&gt;  &lt;li&gt;CA私钥由CA保管，必须确保   &lt;strong&gt;CA私钥的高度机密性&lt;/strong&gt;&lt;/li&gt;  &lt;li&gt;CA公钥在网上公开，必须保证   &lt;strong&gt;CA公钥的完整性&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;  &lt;code&gt;为什么需要PKI&lt;/code&gt;?&lt;/p&gt; &lt;p&gt;  &lt;strong&gt;身份认证&lt;/strong&gt;的目的是要确定对方的身份是否是  &lt;strong&gt;真实&lt;/strong&gt;或  &lt;strong&gt;合法的&lt;/strong&gt;，为了达到这一目的，需要建立初始信任(双方已经共享了的  &lt;strong&gt;秘密&lt;/strong&gt;)，但在网络环境下，建立初始信任需要建立一条  &lt;strong&gt;安全通道&lt;/strong&gt;，这一任务在公钥密码提出之前是非常困难的，代价也很高。而公钥密码提出后，可以用公钥密码手段(  &lt;strong&gt;一个公钥，一个私钥，用公钥传递私钥&lt;/strong&gt;)传递  &lt;strong&gt;秘密&lt;/strong&gt;，如Diffie-Hellman。但  &lt;strong&gt;公钥的真实性&lt;/strong&gt;又难以保证，如何确定一个人和他所持有的公钥的关系，已经公钥是否在有效期内，签名算法是什么？所以  &lt;strong&gt;可信的第三方系统&lt;/strong&gt;被提了出来，如A与B想建立一条安全路径时，可以寻找共同信任的第三方，在可信第三方的帮助下实现A对B所拥有的  &lt;strong&gt;公钥的鉴别&lt;/strong&gt;，从而建立初始信任。&lt;/p&gt; &lt;p&gt;而PKI就是这样一个  &lt;strong&gt;第三方系统&lt;/strong&gt;，可以让可信第三方(  &lt;strong&gt;CA&lt;/strong&gt;)对用户的公钥  &lt;strong&gt;签署证书&lt;/strong&gt;，只要验证证书的合法性，就可以相信  &lt;strong&gt;公钥证书&lt;/strong&gt;中所描述的  &lt;strong&gt;关于公钥的信息&lt;/strong&gt;，如证书主体，有效期等证书域是可信的。&lt;/p&gt; &lt;h2&gt;  &lt;a href="https://luo41.top/#&amp;#35748;&amp;#35777;&amp;#21327;&amp;#35758;"&gt;&lt;/a&gt; 认证协议&lt;/h2&gt; &lt;p&gt;实体认证的两种方式&lt;/p&gt; &lt;p&gt;  &lt;code&gt;弱认证&lt;/code&gt;：基于口令的认证&lt;/p&gt; &lt;p&gt;  &lt;code&gt;强认证&lt;/code&gt;：质询-应答协议&lt;/p&gt; &lt;h3&gt;  &lt;a href="https://luo41.top/#&amp;#24369;&amp;#35748;&amp;#35777;"&gt;&lt;/a&gt; 弱认证&lt;/h3&gt; &lt;p&gt;用户提供一个口令，计算机验证该口令，如果输入的口令和该用户相对应的口令(  &lt;strong&gt;可能存放在数据库中&lt;/strong&gt;)对比不一致，则用户的身份得到认证，否则拒绝该口令，认证失败。&lt;/p&gt; &lt;p&gt;  &lt;code&gt;口令的脆弱性&lt;/code&gt;：&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;   &lt;p&gt;字典攻击(    &lt;strong&gt;在线，离线&lt;/strong&gt;)：攻击者可以    &lt;strong&gt;穷举字典&lt;/strong&gt;的口令，猜测出特定用户的口令，但需要有两个条件：&lt;/p&gt;   &lt;ol&gt;    &lt;li&gt;口令在字典中&lt;/li&gt;    &lt;li&gt;可以判断选用的口令是否正确&lt;/li&gt;&lt;/ol&gt;   &lt;p&gt;因此要尽量避免    &lt;strong&gt;口令泄露&lt;/strong&gt;    &lt;br /&gt;    &lt;code&gt;口令又是如何泄露的呢？&lt;/code&gt;&lt;/p&gt;   &lt;ol&gt;    &lt;li&gt;     &lt;p&gt;网络明文传输&lt;/p&gt;&lt;/li&gt;    &lt;li&gt;     &lt;p&gt;口令文件非法访问&lt;/p&gt;     &lt;p&gt;      &lt;code&gt;解决的办法&lt;/code&gt;：使用一个单向的hash函数将口令hash成      &lt;strong&gt;伪随机数&lt;/strong&gt;。对口令进行散列(      &lt;strong&gt;加盐&lt;/strong&gt;)&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;工作站劫持&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;用户误用&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;搭线窃听&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;h3&gt;  &lt;a href="https://luo41.top/#&amp;#24378;&amp;#35748;&amp;#35777;"&gt;&lt;/a&gt; 强认证&lt;/h3&gt; &lt;p&gt;这部分协议主要就是发送一个数，用  &lt;strong&gt;密钥&lt;/strong&gt;进行验证或解密，我个人还不是很熟悉。&lt;/p&gt; &lt;h2&gt;  &lt;a href="https://luo41.top/#&amp;#23433;&amp;#20840;&amp;#31574;&amp;#30053;&amp;#35775;&amp;#38382;&amp;#25511;&amp;#21046;"&gt;&lt;/a&gt; 安全策略，访问控制&lt;/h2&gt; &lt;h3&gt;  &lt;a href="https://luo41.top/#&amp;#23433;&amp;#20840;&amp;#31574;&amp;#30053;"&gt;&lt;/a&gt; 安全策略&lt;/h3&gt; &lt;p&gt;安全策略  &lt;strong&gt;为系统定义安全&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;安全策略将系统状态划分为两类&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;   &lt;strong&gt;授权状态&lt;/strong&gt; Authorized 系统允许进入的状态，安全的&lt;/li&gt;  &lt;li&gt;   &lt;strong&gt;非授权状态&lt;/strong&gt; Unauthorized 不安全的，如果系统进入这些状态，则违反了安全规定&lt;/li&gt;&lt;/ul&gt; &lt;h3&gt;  &lt;a href="https://luo41.top/#&amp;#23433;&amp;#20840;&amp;#31995;&amp;#32479;"&gt;&lt;/a&gt; 安全系统&lt;/h3&gt; &lt;h4&gt;  &lt;a href="https://luo41.top/#&amp;#23450;&amp;#20041;&amp;#19968;"&gt;&lt;/a&gt; 定义一&lt;/h4&gt; &lt;p&gt;安全系统是一种  &lt;code&gt;始于已授权状态，但不能进入未授权状态&lt;/code&gt;的系统。&lt;/p&gt; &lt;h4&gt;  &lt;a href="https://luo41.top/#&amp;#23450;&amp;#20041;&amp;#20108;"&gt;&lt;/a&gt; 定义二&lt;/h4&gt; &lt;p&gt;如果系统进入了一个未授权状态，则称发生了一次安全破坏&lt;/p&gt; &lt;h4&gt;  &lt;a href="https://luo41.top/#&amp;#23450;&amp;#20041;&amp;#19977;"&gt;&lt;/a&gt; 定义三&lt;/h4&gt; &lt;p&gt;  &lt;strong&gt;保密性&lt;/strong&gt;：设X是实体的集合，并设I是信息，如果X中成员不能获取信息I，那么I关于X具有  &lt;strong&gt;保密性&lt;/strong&gt;。&lt;/p&gt; &lt;h4&gt;  &lt;a href="https://luo41.top/#&amp;#23450;&amp;#20041;&amp;#22235;"&gt;&lt;/a&gt; 定义四&lt;/h4&gt; &lt;p&gt;  &lt;strong&gt;完整性&lt;/strong&gt;：设X是实体的集合，并设I是某些信息或某种资源，如果X中所有成员都信任I，那么I关于X具有  &lt;strong&gt;完整性&lt;/strong&gt;。&lt;/p&gt; &lt;h4&gt;  &lt;a href="https://luo41.top/#&amp;#23450;&amp;#20041;&amp;#20116;"&gt;&lt;/a&gt; 定义五&lt;/h4&gt; &lt;p&gt;  &lt;strong&gt;可用性&lt;/strong&gt;：设X是实体的集合，并设I是一种资源，如果X中所有的成员都可以访问I，那么I关于X是具有  &lt;strong&gt;可用性&lt;/strong&gt;的。&lt;/p&gt; &lt;p&gt;以上  &lt;strong&gt;保密性&lt;/strong&gt;，  &lt;strong&gt;完整性&lt;/strong&gt;，  &lt;strong&gt;可用性&lt;/strong&gt;的定义都用到了集合的方法来表达，小结&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;   &lt;strong&gt;不可获取信息&lt;/strong&gt;(保密)&lt;/li&gt;  &lt;li&gt;   &lt;strong&gt;信任&lt;/strong&gt;(完整性)&lt;/li&gt;  &lt;li&gt;   &lt;strong&gt;访问的服务质量&lt;/strong&gt;(可用性)&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;与ISO的CIA定义的区别是：  &lt;code&gt;此处没有攻击者&lt;/code&gt;&lt;/p&gt; &lt;h4&gt;  &lt;a href="https://luo41.top/#&amp;#23450;&amp;#20041;&amp;#20845;"&gt;&lt;/a&gt; 定义六&lt;/h4&gt; &lt;p&gt;安全机制是实施安全策略的某些部分的实体或规程。&lt;/p&gt; &lt;h4&gt;  &lt;a href="https://luo41.top/#&amp;#23450;&amp;#20041;&amp;#19971;"&gt;&lt;/a&gt; 定义七&lt;/h4&gt; &lt;p&gt;安全模型是表达特定策略或策略集合的模型。&lt;/p&gt; &lt;h4&gt;  &lt;a href="https://luo41.top/#&amp;#20004;&amp;#20010;&amp;#32467;&amp;#35770;"&gt;&lt;/a&gt; 两个结论&lt;/h4&gt; &lt;ol&gt;  &lt;li&gt;计算机系统的安全性是不可判定问题&lt;/li&gt;  &lt;li&gt;判断一个程序是否为病毒是不可判定问题&lt;/li&gt;&lt;/ol&gt; &lt;h3&gt;  &lt;a href="https://luo41.top/#&amp;#35775;&amp;#38382;&amp;#25511;&amp;#21046;"&gt;&lt;/a&gt; 访问控制&lt;/h3&gt; &lt;p&gt;  &lt;code&gt;&amp;quot;防止未经授权使用资源，包括防止以非授权方式使用资源&amp;quot;&lt;/code&gt;，是计算机安全的  &lt;strong&gt;核心元素&lt;/strong&gt;&lt;/p&gt; &lt;h4&gt;  &lt;a href="https://luo41.top/#&amp;#35775;&amp;#38382;&amp;#25511;&amp;#21046;&amp;#31574;&amp;#30053;"&gt;&lt;/a&gt; 访问控制策略&lt;/h4&gt; &lt;ol&gt;  &lt;li&gt;   &lt;p&gt;    &lt;strong&gt;自主访问控制&lt;/strong&gt; DAC&lt;/p&gt;   &lt;ul&gt;    &lt;li&gt;基于请求者的身份和访问规则&lt;/li&gt;    &lt;li&gt;实体可授权&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;    &lt;strong&gt;强制访问控制&lt;/strong&gt; MAC&lt;/p&gt;   &lt;ul&gt;    &lt;li&gt;     &lt;p&gt;基于安全许可(      &lt;strong&gt;实体的能力&lt;/strong&gt;)和安全标记(      &lt;strong&gt;资源的敏感度&lt;/strong&gt;)&lt;/p&gt;&lt;/li&gt;    &lt;li&gt;     &lt;p&gt;实体不可对另一实体授权&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;    &lt;strong&gt;基于角色的访问控制&lt;/strong&gt; RBAC&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt; &lt;h4&gt;  &lt;a href="https://luo41.top/#&amp;#35775;&amp;#38382;&amp;#25511;&amp;#21046;&amp;#30340;&amp;#22522;&amp;#26412;&amp;#20803;&amp;#32032;"&gt;&lt;/a&gt; 访问控制的基本元素&lt;/h4&gt; &lt;ol&gt;  &lt;li&gt;   &lt;strong&gt;主体&lt;/strong&gt; - entity that can access objects   &lt;ul&gt;    &lt;li&gt;进程&lt;/li&gt;    &lt;li&gt;三类：owner，group，world&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;  &lt;li&gt;   &lt;strong&gt;客体&lt;/strong&gt; access controlled resource   &lt;ul&gt;    &lt;li&gt;资源&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;  &lt;li&gt;   &lt;strong&gt;访问权&lt;/strong&gt; way in which subject accessed an object   &lt;ul&gt;    &lt;li&gt;e.g read，write，execute，delete，create&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ol&gt; &lt;h3&gt;  &lt;a href="https://luo41.top/#&amp;#33258;&amp;#20027;&amp;#35775;&amp;#38382;&amp;#25511;&amp;#21046;"&gt;&lt;/a&gt; 自主访问控制&lt;/h3&gt; &lt;ul&gt;  &lt;li&gt;访问控制矩阵   &lt;ul&gt;    &lt;li&gt;主体：     &lt;strong&gt;行&lt;/strong&gt;&lt;/li&gt;    &lt;li&gt;客体：     &lt;strong&gt;列&lt;/strong&gt;&lt;/li&gt;    &lt;li&gt;矩阵元素：     &lt;strong&gt;权限&lt;/strong&gt;(访问权)&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;但在一个系统中，访问控制矩阵会显得很大，因为其中有许多的矩阵元素是0(也就是主体和客体毫无关系的)，改进思路：  &lt;strong&gt;稀疏矩阵&lt;/strong&gt;，  &lt;strong&gt;可分解&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;  &lt;code&gt;访问控制列表ACL&lt;/code&gt;&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;概念上，ACL就像访问控制矩阵的列。&lt;/li&gt;  &lt;li&gt;针对每一个客体，列出   &lt;strong&gt;用户和权限&lt;/strong&gt;&lt;/li&gt;  &lt;li&gt;特点：简化，高效&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;  &lt;code&gt;能力表&lt;/code&gt;：又称能力权证，C-List&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;概念上能力表就像访问控制矩阵的行。&lt;/li&gt;  &lt;li&gt;针对用户，指示用户所能访问的   &lt;strong&gt;客体及其权限&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;  &lt;code&gt;ACL与C-List比较&lt;/code&gt;&lt;/p&gt; &lt;p&gt;给定主题，确定它能访问哪些客体，访问的权限是？&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;使用能力表更简单&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;给定客体，确定有哪些主体能够访问，访问的权限是？&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;使用访问控制表回答简单&lt;/li&gt;&lt;/ul&gt; &lt;h3&gt;  &lt;a href="https://luo41.top/#&amp;#24378;&amp;#21046;&amp;#24615;&amp;#35775;&amp;#38382;&amp;#25511;&amp;#21046;"&gt;&lt;/a&gt; 强制性访问控制&lt;/h3&gt; &lt;ul&gt;  &lt;li&gt;基于安全许可(   &lt;strong&gt;实体的能力&lt;/strong&gt;)和安全标记(   &lt;strong&gt;资源的敏感度&lt;/strong&gt;)&lt;/li&gt;  &lt;li&gt;实体不可对另一实体授权&lt;/li&gt;&lt;/ul&gt; &lt;h4&gt;  &lt;a href="https://luo41.top/#blp&amp;#27169;&amp;#22411;"&gt;&lt;/a&gt; BLP模型&lt;/h4&gt; &lt;p&gt;按线性排列定义  &lt;strong&gt;安全许可&lt;/strong&gt;(clearance)，对应于军事安全中的安全许可&lt;/p&gt; &lt;ol&gt;  &lt;li&gt;Top Secret (TS)：最高&lt;/li&gt;  &lt;li&gt;Secret (S)&lt;/li&gt;  &lt;li&gt;Confidential ©&lt;/li&gt;  &lt;li&gt;Unclassified (UC)：最低&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;主体有安全许可，客体有安全密级，有时候统称为  &lt;strong&gt;安全密级&lt;/strong&gt;&lt;/p&gt; &lt;img src="https://luo41.top/2022/01/20/ComSec%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%AE%89%E5%85%A8OverView/3.png"&gt;&lt;/img&gt; &lt;p&gt;BLP模型：&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;   &lt;p&gt;防止主体读取安全密级比它的安全许可更高的客体。&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;    &lt;code&gt;简单安全条件&lt;/code&gt;，预备版本：S可以读O，当且仅当lo&amp;lt;=ls，且S对O具有自主性读权限&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;具有自主型读权限，意味着与自主访问控制部分相对应的S和O的访问控制矩阵条目中包含    &lt;strong&gt;一项读的权限&lt;/strong&gt;。&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;*-属性(    &lt;strong&gt;星号属性&lt;/strong&gt;)，预备版本：S可以写O，当且仅当ls&amp;lt;=lo，且S对O具有自主型写权限。&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;    &lt;code&gt;基本安全定理&lt;/code&gt;，预备版本：设系统的的某一个    &lt;strong&gt;初始安全状态为&lt;/strong&gt;σ0\sigma_{0}σ0​，T是状态转换的集合。如果T的每个元素都遵守    &lt;strong&gt;简单安全条件&lt;/strong&gt;(预备版)和*-属性(预备版)，那么对于每个i&amp;gt;=0，状态σi\sigma_{i}σi​都是安全的。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;  &lt;code&gt;小结Bell-LaPadula模型：&lt;/code&gt;&lt;/p&gt; &lt;ol&gt;  &lt;li&gt;简单安全条件：   &lt;strong&gt;不向上读&lt;/strong&gt;(no reads up)&lt;/li&gt;  &lt;li&gt;*-属性：   &lt;strong&gt;不向下写&lt;/strong&gt;(no writes down)&lt;/li&gt;  &lt;li&gt;基本安全定理，如果初始状态为安全的系统，且所有状态转换都满足简单安全条件和星号属性，则系统中的所有状态都是安全的。&lt;/li&gt;  &lt;li&gt;本质是   &lt;strong&gt;强制型访问控制&lt;/strong&gt;，但结合了自主型访问控制的内容。&lt;/li&gt;&lt;/ol&gt; &lt;h3&gt;  &lt;a href="https://luo41.top/#&amp;#22522;&amp;#20110;&amp;#35282;&amp;#33394;&amp;#30340;&amp;#35775;&amp;#38382;&amp;#25511;&amp;#21046;"&gt;&lt;/a&gt; 基于角色的访问控制&lt;/h3&gt; &lt;ul&gt;  &lt;li&gt;基于角色而非身份的控制&lt;/li&gt;  &lt;li&gt;基于角色授权，而不是单独给用户授权&lt;/li&gt;&lt;/ul&gt; &lt;img src="https://luo41.top/2022/01/20/ComSec%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%AE%89%E5%85%A8OverView/4.png"&gt;&lt;/img&gt; &lt;p&gt;参考资料：&lt;/p&gt; &lt;ol&gt;  &lt;li&gt;   &lt;p&gt;bintou老师课件&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;《密码与编码学与网络安全》第七版&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>学习笔记 计算机安全</category>
      <guid isPermaLink="true">https://itindex.net/detail/62047-comsec-%E6%A6%82%E5%BF%B5</guid>
      <pubDate>Thu, 20 Jan 2022 20:11:16 CST</pubDate>
    </item>
    <item>
      <title>SRE 的工作介绍</title>
      <link>https://itindex.net/detail/61879-sre-%E5%B7%A5%E4%BD%9C</link>
      <description>&lt;p&gt;有很多人问过我想了解一下 SRE 这个岗位，这是个很大的话题，在这篇博客中把想到的一些介绍一下吧。&lt;/p&gt;
 &lt;p&gt;SRE 到底是什么？这是一个最早由 Google 提出的概念，我的理解是，用软件解决运维问题。标准化，自动化，可扩展，高可用是主要的工作内容。这个岗位被提出的时候，想解决的问题是打破开发人员想要快速迭代，与运维人员想要保持稳定，拒绝频繁更新之间的矛盾。&lt;/p&gt;
 &lt;p&gt;SRE 目前对于招聘来说还是比较困难。一方面，这个岗位需要一定的经验，而应届生一般来说不会有运维复杂软件的经历；另一方面就是很多人依然以为这就是“运维”工程师，认为做的是一些低级重复的工作，对这个工作有排斥。最根本的，其实这个岗位寻找的要么是具有运维经验的开发人员，要么是具有软件开发技能的运维工程师。所以比较难以找到合适的人。&lt;/p&gt;
 &lt;p&gt;在现实生活中，不同公司的 SRE 岗位大有不同，有一些甚至可能还是传统运维的名字换了一个岗位名称。&lt;/p&gt;
 &lt;p&gt;比如蚂蚁金服有两种 SRE，一种是负责稳定性的，就是大家所理解的 SRE；另一种叫做资金安全 SRE，并不负责服务正常运行，而是负责金钱数目正确，对账没有错误，工作内容以开发为主，主要是资金核对平台和核对规则（没有做过，只是个人理解）。某种意义上说，已经不算是 SRE 而是专业领域的开发了。&lt;/p&gt;
 &lt;p&gt;  &lt;a href="https://www.youtube.com/watch?v=koGaH4ffXaU"&gt;Netflix&lt;/a&gt; （2016年）的模式是谁开发，谁维护。SRE 负责提供技术支持，和咨询服务。Netflix 在全球 170 个国家有服务，Core SREs 只有 5 个人。&lt;/p&gt;
 &lt;p&gt;微软有专门的   &lt;a href="https://azure.microsoft.com/mediahandler/files/resourcefiles/devops-at-microsoft-game-streaming-sre/DevOps%20at%20Microsoft%20-%20Xbox%20game%20streaming%20SRE.pdf"&gt;Game Streaming SRE&lt;/a&gt;，负责 XBox 在线游戏的稳定性。&lt;/p&gt;
 &lt;p&gt;所以不同公司的 SRE 的内容各有偏重，取决于公司要提供什么样的服务。&lt;/p&gt;
 &lt;p&gt;我们可以学习网络分层的方式，将 SRE 大致的工作内容从下往上分成 3 个大类：&lt;/p&gt;
 &lt;ol&gt;
  &lt;li&gt;Infrastructure：主要负责最基础的硬件设施，网络，类似于 IaaS，做的事情可参考 DigitalOcean&lt;/li&gt;
  &lt;li&gt;Platform：提供中间件技术，开箱即用的一些服务，类似于 PaaS，做的事情可参考 Heroku, GCP, AWS 等&lt;/li&gt;
  &lt;li&gt;业务 SRE：维护服务，应用，维护业务的正常运行&lt;/li&gt;
&lt;/ol&gt;
 &lt;h2&gt;Infrastructure&lt;/h2&gt;
 &lt;p&gt;Infrastructure 和 Platform SRE 其实可有可无，这些年商业化的服务其实越来越多了，比如，如果公司选择全部在 AWS 部署自己的服务的话，那么就不需要自己建立 Datacenter，维护网络之类的工作了，只需要几个 AWS 专家即可。&lt;/p&gt;
 &lt;p&gt;如果有的话，工作内容也可大可小。可以从管理购买的 VPS 开始，也可以从采购硬件服务器开始。&lt;/p&gt;
 &lt;p&gt;我觉得 Infrastructure SRE 的工作内容可以这样定义：&lt;/p&gt;
 &lt;ol&gt;
  &lt;li&gt;负责服务器的采购，预算，CMDB 管理。要知道（能查询到）每一台的负责人是谁，在干什么。这个非常重要，如果做不好，会造成极大的资源浪费。&lt;/li&gt;
  &lt;li&gt;提供可靠软件的部署环境，一般是虚拟机，或者 bare mental。&lt;/li&gt;
  &lt;li&gt;操作系统的版本统一维护，Linux 发行版的版本，Kernel 的版本等。&lt;/li&gt;
  &lt;li&gt;维护机器上的基础软件，比如 NTP，监控代理，其他的一些代理。&lt;/li&gt;
  &lt;li&gt;提供机器的登录方式，权限管理，命令审计。&lt;/li&gt;
  &lt;li&gt;维护一套可观测性的基础设施，比如监控系统，log 系统，trace 系统。&lt;/li&gt;
  &lt;li&gt;维护网络，大公司可能都会自己设计机房内的网络。其中包括：
   &lt;ol&gt;
    &lt;li&gt;网络的连通，这个是必要的。对于上层用户（Platform SRE）来说，交付的服务应该是任意两个 IP 是可以 ping 通的，即管理好 3 层以下的网络。&lt;/li&gt;
    &lt;li&gt;NAT 服务&lt;/li&gt;
    &lt;li&gt;DNS 服务&lt;/li&gt;
    &lt;li&gt;防火墙&lt;/li&gt;
    &lt;li&gt;4 层负载均衡，7层负载均衡&lt;/li&gt;
    &lt;li&gt;CDN&lt;/li&gt;
    &lt;li&gt;证书管理&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
 &lt;p&gt;每一项既可以是一个很大的团队，也可以只有一个人去对商业化的 Infra 服务。可以使用开源的产品，也可以自己研发。&lt;/p&gt;
 &lt;h2&gt;Platform SRE&lt;/h2&gt;
 &lt;p&gt;Infrastructure SRE 维护的是基础设施，Platform SRE 使用他们提供的基础设施建立软件服务，让公司内的开发者可以使用开箱即用的软件服务，比如 Queue，Cache，定时任务，RPC 服务等等。&lt;/p&gt;
 &lt;p&gt;主要的工作内容有：&lt;/p&gt;
 &lt;ol&gt;
  &lt;li&gt;RPC 服务：让不同的服务可以互相发现并调用&lt;/li&gt;
  &lt;li&gt;私有云服务&lt;/li&gt;
  &lt;li&gt;队列服务，比如 Kafka 或者 RabbitMQ&lt;/li&gt;
  &lt;li&gt;分布式的 cronjob 服务&lt;/li&gt;
  &lt;li&gt;Cache&lt;/li&gt;
  &lt;li&gt;网关服务：反向代理的配置&lt;/li&gt;
  &lt;li&gt;对象存储：s3&lt;/li&gt;
  &lt;li&gt;其他一些数据库：ES，mongo 等等。一般来说，关系型数据库会有 DBA 来运维，但是 NoSQL 或者图数据库一般由 SRE 维护。&lt;/li&gt;
  &lt;li&gt;内部的开发环境：
   &lt;ol&gt;
    &lt;li&gt;SCM 系统，比如自建的 Gitlab&lt;/li&gt;
    &lt;li&gt;CI/CD 系统&lt;/li&gt;
    &lt;li&gt;镜像系统，比如 Harbor&lt;/li&gt;
    &lt;li&gt;其他的一些开发工具，比如分布式编译，Sentry 错误管理等等&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
  &lt;li&gt;一些离线计算环境，大数据的服务&lt;/li&gt;
&lt;/ol&gt;
 &lt;h2&gt;业务 SRE&lt;/h2&gt;
 &lt;p&gt;有了 Platform SRE 的支持，开发人员写代码就基本上不需要关心部署的问题了。可以专注于开发，使用公司开箱即用的服务。这一层的 SRE 更加贴近于业务，知道业务是怎么运行的，请求是怎么处理的，依赖了哪些组件。如果 X 除了问题，可以有哪些降级策略。参与应用的架构设计，提供技术支持。&lt;/p&gt;
 &lt;p&gt;主要的工作内容有：&lt;/p&gt;
 &lt;ol&gt;
  &lt;li&gt;参与系统的设计。比如熔断、降级，扩容等策略。&lt;/li&gt;
  &lt;li&gt;做压测，了解系统的容量。&lt;/li&gt;
  &lt;li&gt;做容量规划。&lt;/li&gt;
  &lt;li&gt;业务侧的 Oncall。&lt;/li&gt;
&lt;/ol&gt;
 &lt;p&gt;对于一个专业的 SRE 来说，上述技能也不应该有明显的界限，比如说业务 SRE 也需要掌握一些网络技能，Infra SRE 也要写一些代码。很多工具每一个岗位的人都多少用的到，比如 Ansible/Puppet/SaltStack 这种 IT 自动化工具，或者 Grafana/Prometheus 这种监控工具，只有理解才能用的正确。换个角度讲，对于业务 SRE 来说，虽然基本上不会去管理四层以下的网络，但是如果遇到网络问题，能通过已有的工具和权限排查到交换机问题，去找 Infra SRE 帮忙：“请帮我看下 xx IP 到交换机是否有异常，因为 xxx 显示的结果是 xx”，总比 “我怀疑 xx 有网络问题，请帮忙排查下” 要好一些吧？&lt;/p&gt;
 &lt;p&gt;以上是工作职责的大体划分，这个分层其实没有什么意义，倒是可以让读者了解一下 SRE 都涉及哪一些工作。&lt;/p&gt;
 &lt;p&gt;下面是一些日常的工作内容。&lt;/p&gt;
 &lt;h2&gt;部署服务&lt;/h2&gt;
 &lt;p&gt;部署分成两种：&lt;/p&gt;
 &lt;ol&gt;
  &lt;li&gt;Day 1：将服务部署上线的那一天&lt;/li&gt;
  &lt;li&gt;Day 2+：服务部署之后，还会进行很多更新，升级，配置更改，服务迁移等等&lt;/li&gt;
&lt;/ol&gt;
 &lt;p&gt;Day2+ 的工作要做很多次，Day 1 做的很少，在不断的迭代升级之后，还能保证有一个可靠的 Day 1 操作是很难的。换句话说，我们在服务部署之后一直改来改去，还要保证这个服务在一个全新的环境能够可靠的部署起来。部署环境的硬编码，奇奇怪怪的 work around，都会破坏 Day 1 的可靠性。之前一家公司，扩容一个新机房的过程简直是噩梦，太多的奇怪配置，hardcode，导致踩过无数个坑才能在一个新的机房部署起来全部的服务。&lt;/p&gt;
 &lt;p&gt;Day2+ 的操作也不简单，主要要关注稳定性。对于重要的变更操作要设计好变更计划，如何做到灰度测试，如果出了问题应该如何回滚，如何保证回滚可以成功（如何测试回滚）等等。&lt;/p&gt;
 &lt;p&gt;部署的操作最好都是可以追踪的，因为并不是所有会引起问题的操作都会立即引起问题。比如一个操作当时做完没有什么问题，但是过了 1 个月，偶然的重启或者内存达到了某一个指标触发了问题。如果能记录操作的话，我们可以回溯之前做过的变更，方便定位问题。现在一般都用 git 来追踪部署过程的变更（  &lt;a href="https://www.weave.works/technologies/gitops/"&gt;gitops&lt;/a&gt;）。&lt;/p&gt;
 &lt;h2&gt;Oncall&lt;/h2&gt;
 &lt;p&gt;Oncall 简单来说就是要保证线上服务的正常运行。典型的工作流程是：收到告警，检查告警发出的原因，确认线上服务是否有问题，定位到问题，解决问题。&lt;/p&gt;
 &lt;p&gt;收到告警并不总意味着真正的问题，也有可能告警设置的不合理。告警和监控面板并不是一个静态的配置，它应该是每天都在变化的，时刻在调整的。如果发现没有标志真正线上问题的告警发了出来，就应该修改告警规则。如果发现当前的监控无法快速定位问题，应该调整监控面板，添加或者删除监控指标。业务在发展，请求量在变化，某些阈值也需要不断地调整。&lt;/p&gt;
 &lt;p&gt;定位问题没有一概而论的方法了，需要根据看到的实时，结合自己的经验，然后做推测，然后使用工具验证自己的推测，然后确定问题的根因。&lt;/p&gt;
 &lt;p&gt;但是解决问题是可以有方法论的，叫做   &lt;a href="https://en.wikipedia.org/wiki/Standard_operating_procedure"&gt;SOP，标准操作流程&lt;/a&gt;。即：如果出现了这种现象，那么执行那种操作，就可以恢复业务。SOP 文档应该提前制定，并且验证其有效性。&lt;/p&gt;
 &lt;p&gt;需要注意的是上述定位问题、解决问题  &lt;strong&gt;并没有顺序关系&lt;/strong&gt;。一个经常犯的错误是，在出现故障的时候，花了很长时间定位到故障的根因，然后再修复。这样花的时间一般会比较长。正确的做法是先根据现象看现有的 SOP 能否恢复业务。比如说当前错误只发生在某一个节点上，那么就直接下线这个节点，具体的原因后面再排查。恢复当前的故障永远是第一要务。但是恢复操作也要经过测试，比如猜测可以通过重启解决问题的话，可以先重启一台做测试，而不是一次性将所有服务重启。大部分情况是需要临场分析的，是一个紧张又刺激的过程。&lt;/p&gt;
 &lt;p&gt;故障到底多久恢复算好？出现多少故障是可以容忍的？怎么标志服务的稳定性到底如何？我们使用 SLI/SLO 来衡量这些问题。&lt;/p&gt;
 &lt;h2&gt;制定和交付 SLI/SLO&lt;/h2&gt;
 &lt;p&gt;维护服务等级协议，听起来像是一个非常简单的事情，只要“设定一个可用率”然后去实现它就好了。然而现实的情况并不是。&lt;/p&gt;
 &lt;p&gt;比如，制定可用率的时候，并不是说我们去“实现4个9”（99.99% 的时间可用）就够了，我们有以下问题要考虑：&lt;/p&gt;
 &lt;ol&gt;
  &lt;li&gt;如何定义这个可用率？比如我们以可用率 &amp;gt; 99.9% 为目标，有一个服务部署了 5 个 Zone, 那么有一个 Zone 挂了，其余的 Zone 是可用的，那么可用率被破坏了吗？这个可用率是每一个 Zone 的还是所有的 Zone 一起计算的？&lt;/li&gt;
  &lt;li&gt;可用率计算的最小单位是什么？如果 1min 内有 50s 没有达到可用率，那么这一分钟算是 down 还是 up？&lt;/li&gt;
  &lt;li&gt;可用率的周期是怎么计算的？按照一个月还是一个周？一个周是最近的 7 天还是计算一个自然周？&lt;/li&gt;
  &lt;li&gt;如何对 SLI 和 SLO 做监控？&lt;/li&gt;
  &lt;li&gt;如果错误预算即将用完，有什么措施？比如减少发布？如果 SLI 和 SLO 没有达到会怎么样？&lt;/li&gt;
&lt;/ol&gt;
 &lt;p&gt;等等，如果这些问题不考虑清楚的话，那么 SLI 和 SLO 很可能就是没有意义的。SLI/SLO 也适用于对公司内部用户的承诺，让用户对我们的服务有预期，而不能有盲目的信任。比如 Google 在 SLI/SLO 还有预算的时候，会在满足 SLI/SLO 的时候自行对服务做一些破坏，让用户不要对服务有 100% 可用的错误预期。SLI/SLO 也会让 SRE 自己对当前服务的稳定性有更好的认识，可以根据此调整运维、变更、发布计划。&lt;/p&gt;
 &lt;h2&gt;故障复盘&lt;/h2&gt;
 &lt;p&gt;故障复盘的唯一目的是减少故障的发生。有几个我目前认为不错的做法。&lt;/p&gt;
 &lt;p&gt;故障复盘需要有文档记录，包括故障发生的过程，时间线的记录，操作的记录，故障恢复的方法，故障根因的分析，为什么故障会发生的分析。文档应该隐去所有当事人的姓名对公司的所有人公开。很多公司对故障文档设置查看权限，我觉得没什么道理。有些公司的故障复盘甚至  &lt;a href="https://github.com/danluu/post-mortems"&gt;对外也是公开的&lt;/a&gt;。&lt;/p&gt;
 &lt;p&gt;故障在复盘的时候应该将当事人的名字用代码替代，可以营造更好的讨论氛围。&lt;/p&gt;
 &lt;p&gt;不应该要求所有的故障复盘都产生 Action。之前一家的公司的故障复盘上，因为必须给领导一个“交待”，所以每次都会产生一些措施来预防相同的故障再次发生，比如增加审批流程之类的。这很扯，让级别很高的领导审批他自己也看不懂的操作，只能让领导更痛苦，也让操作流程变得又臭又长，最后所有人都会忘记这里为什么会有一个审批，但是又没有人敢删掉。你删掉，出了事情你负责。&lt;/p&gt;
 &lt;p&gt;Blame Free 文化？之前我认为是好的。但是后来发现，有些不按照流程操作导致的问题确实多少应该 Blame 一下，比如下线服务的时候没有检查还没有 tcp 连接就直接下线了，或者操作的时候没有做 canary 就全部操作了，这种不理智的行为导致的故障。但是条条框框又不应该太多，不然活都没法干了。&lt;/p&gt;
 &lt;h2&gt;容量规划&lt;/h2&gt;
 &lt;p&gt;容量规划是一个非常复杂的问题，甚至有一些悖论。容量要提前做好规划，但是容量的规划需要知道业务的扩张速度，扩张速度这种事情又不是提前能计划好的。所以我一直觉得这个事情很难做，也一直没有见过做的很好的例子。&lt;/p&gt;
 &lt;p&gt;但是至少可以对维护的系统建立一个模型，知道多少机器，多少资源，能容纳多少容量。这样遇到大促之类的活动也能及时估算需要的资源数量。&lt;/p&gt;
 &lt;h2&gt;用户支持&lt;/h2&gt;
 &lt;p&gt;用户支持也是日常的一部分。包括技术咨询，以及用户要求的线上问题排查。&lt;/p&gt;
 &lt;p&gt;这里就需要提到文档的重要性了。如果没有维护好文档，那么用户就会一遍又一遍问相同的问题。写文档也是一个技术活，优秀的需要很长时间的积累。文档也需要经常更新。我一般会这样，保持这样一种状态：用户可以不需要任何人就从文档中找到他需要的所有答案。如果我发现用户的问题无法从文档中找到，或者难以找到在文档中的什么地方，就会更新文档，或者重新组织文档。如果用户的问题已经从文档中找到，那么就直接发文档给他。如果用户的问题显然是文档看都没有看过（有很多人根本不看文档的，只看文档是谁写的然后径直去问这个人），就直接忽略。&lt;/p&gt;
 &lt;p&gt;优秀的文档应该尽量引入少的专有名词，少使用没有用处的专业词汇描述，只描述具有指导意义的事实，假定用户没有相关的背景知识，列举使用例子，举一些现实会用到的例子而不是强行举例子，明确 Bad Case。等等。这其实是一个很大的话题了，这里就不展开了。&lt;/p&gt;
 &lt;p&gt;暂时就想到这一些了。下面写一些我经常见到的误解，和经常被别人问的问题。&lt;/p&gt;
 &lt;p&gt; &lt;/p&gt;
 &lt;p&gt;有关做项目没有专业团队得不到训练。&lt;/p&gt;
 &lt;p&gt;这方面是听到最多的抱怨。虽然说 SRE 在工作上应该是开发时间和运维时间各 50%，但是真实的情况是，即使 SRE 有一些开发工作，也大部分是面向内部用户，面向公司内部的开发者的。大部分项目是一些想法，需要去尝试一下行不行，基本上不会有专业的设计资源，PM 资源。这种项目就需要 SRE 有多方面的技能，包括对产品的理解，清楚地知道它有什么痛点，最好是自己经历过的痛点，然后需要懂设计，管理好开发进度。然而这种人非常少。其实能写中型项目代码的 SRE 就已经非常少了。所以大部分公司内部项目都会做的又难用又复杂。&lt;/p&gt;
 &lt;p&gt;即使是有专业配套 PM 和设计，甚至前端资源。基本上也是一个灾难。我也经历过这样的团队。这种内部项目对标的不是互联网项目，而更像是 toB 的项目。用户 UI 的设计，交互逻辑，操作流程，交付周期等需要的都是另一个领域的知识。否则的话人越多，也只会徒增沟通成本，拖慢项目进度。&lt;/p&gt;
 &lt;p&gt;回到经常听到的这个抱怨，说在 SRE 的团队没有像开发团队那样有“正规军”，有设计和 PM，大家各司其职，后端开发只要对齐 API 然后实现就好了。大部分的应届生会有这样的幻想，但实际上不是这样。被搞错的最重要的一点是，  &lt;strong&gt;学习主要是靠自己的，和别人没有太大的关系&lt;/strong&gt;。我觉得可能是在一个大团队里面，有很多人一起做一件事情，心里的怀疑和焦虑会少一点，人们会对这样的工作状态感到踏实，误以为是“成长”，自己做所有的工作焦虑更多。&lt;/p&gt;
 &lt;p&gt;事实是，在大团队工作可能学到更多的沟通技能，比如和不同的人对齐不同的阶段工作目标，要想要学到其他的东西还是要靠自己。比如拿到一个设计，如果照样子去实现了，其实不会学到什么东西。而要去理解为什么这么设计，为什么不那么设计。如果自己去做，思考的过程也基本是这样的，可以怎么设计，选择什么好。都是：思考，选择，尝试，经验，思考……&lt;/p&gt;
 &lt;p&gt;另一个需要澄清的误区是，模仿并不是学习。在团队中经历了一个设计，如果记住了这个设计，下次碰到类似的问题也用这个设计去解决。这也不能叫做是学习。我见过有在业务部门做过支付的 SRE 写的代码，在内部系统中去实现了订单业务的订单、交易等概念完成一个运维流程，甚至 Model 的名字都没改过。拿着锤子找钉子，会让系统变得更加糟糕和复杂。&lt;/p&gt;
 &lt;p&gt;总之，工作分的细并不代表工作就会更加专业。一个人身兼数职业可以在每一个方面做得很专业。重要的是不断学习，使用正确的做事方式，向优秀的项目和优秀的开发者学习。&lt;/p&gt;
 &lt;p&gt; &lt;/p&gt;
 &lt;p&gt;有关脏活累活。&lt;/p&gt;
 &lt;p&gt;每一项工作都会有脏活累活：学不到什么东西，做起来没有意思。可能是整理系统的监控，可能是整理现有的文档，可能清理一些年久的运维脚本，可能是需要和不同的团队做  &lt;a href="https://www.kawabangga.com/posts/4294"&gt;一些沟通工作&lt;/a&gt;等。&lt;/p&gt;
 &lt;p&gt;这是不可避免的，如果可以的话，学会从每一项工作中找一些偷懒的方法吧，比如用脚本处理一些工作，用更聪明的方式工作等等。&lt;/p&gt;
 &lt;p&gt;但是如果这种工作的比例太高的话，就要思考工作方式的问题了。如果陷入恶性循环，看能不能从工具和工作流程上做一些改变。如果不能的话，考虑换一份工作吧。&lt;/p&gt;
 &lt;p&gt; &lt;/p&gt;
 &lt;p&gt;有关背锅。&lt;/p&gt;
 &lt;p&gt;互相甩锅的工作环境无疑是非常糟糕的工作环境。如果相同的团队、或者不同的团队之间需要相互勾心斗角的话，如果工作环境不允许大方承认（SRE 无可避免地会犯一些错误）自己的错误，说明公司营造的氛围有问题。比如某些公司规定，发生 P1 级别的错误就必须开除一个 Px 级别的员工，发生 P0 级别的错误就必须开除一个 Py 级别的员工一样。如果是这种情况的话，公司实际上是在用一种懒惰地方法通过提高人的压力来提高系统的稳定性。有没有效果不知道，但是确定的是不会有人在这种情况下工作的开心。建议换一份工作。&lt;/p&gt;
 &lt;p&gt; &lt;/p&gt;
 &lt;p&gt;如何转行？&lt;/p&gt;
 &lt;p&gt;其实难度没有想象的高，毕竟大学里面没有一个叫做 SRE 的专业。SRE 要求的知识也是编写代码、设计系统、了解操作系统和网络等。所以在大学里面将本科的课程好好学好，尝试做（并维护）一些自己的项目，毕业的时候基本上就满足要求了。非科班的人要转行的话，也可以参考大学的课程内容去补足这方面的知识。&lt;/p&gt;
 &lt;p&gt;需要注意的是，培训班出来的做开发完成业务可能够，但是做 SRE 远远不够。SRE 不仅需要 make things work，还要知道背后的原理。&lt;/p&gt;
 &lt;p&gt; &lt;/p&gt;
 &lt;p&gt;面试会问什么？&lt;/p&gt;
 &lt;p&gt;我觉得和后端开发的面试内容基本上差不多。&lt;/p&gt;
 &lt;p&gt;如果是去应聘的这个岗位所需要的一些技能，比如 K8S，监控系统等，可能也会问一些领域内的知识。虽说这部分工具性的东西都可以学习，但是如果人家要一个经验丰富的、或者入职就能干活的，那么面试成功的机会就会小很多。当然，也不必沮丧，这是市场的供需关系决定的，如果对方执意要找符合特定要求的候选人，那么对方的选择的范围也会小很多，不必因为错失了这种机会而后悔没去学习什么工具。话又说回来，技能越多，选择也会越多。&lt;/p&gt;
 &lt;p&gt;排查错误可能是转行做 SRE 最大的一个门槛，这个需要一些经验。如果没有经验的话，就补足一些操作系统的知识，这样遇到未知的问题也可以通过已知的知识和工具去排查。&lt;/p&gt;
 &lt;p&gt; &lt;/p&gt;
 &lt;p&gt;做 SRE 需要会写代码吗？&lt;/p&gt;
 &lt;p&gt;会，而且写代码的要求并不会比一个专业的后端开发低。&lt;/p&gt;
 &lt;p&gt; &lt;/p&gt;
 &lt;p&gt;选择大公司还是小公司？&lt;/p&gt;
 &lt;p&gt;这属于两种截然不同的工作环境。小公司一般都有一个救火英雄式的人物，在公司的时间比较长，知道所有组件的部署结构，什么都懂。跟着这种人学习会成长很快。&lt;/p&gt;
 &lt;p&gt;大公司细分领域很多。本文前面列出的内容可能每一项在大公司中都是一个团队，对某个领域可以深入研究。&lt;/p&gt;
 &lt;p&gt;所以还是看想要做什么了。我个人比较喜欢靠谱的小公司，或者大公司中靠谱的小团队。&lt;/p&gt;
 &lt;p&gt; &lt;/p&gt;
 &lt;p&gt;如何判断一家公司是否靠谱？&lt;/p&gt;
 &lt;p&gt;对于 SRE 这个职位，我总结了一些判断的技巧。比如可以判断一下对方目前的业务和 SRE 员工的数量是否处于一个“正常”的状态，人数是否在随着业务（机器的数量）现象增长？这是一个不好的迹象。是否 SRE 的数量过多？如果 SRE 人太多，有两个可能的原因：1）某个领导为了扩大自己的影响力在为一些“不必要的”岗位招人，这样会导致人多事少，大家开始做一些奇奇怪怪的事情，发明奇奇怪怪的需求，以各种各样的方式浪费自己的时间来领公司的工资；2）这个公司的基础太差，大部分工作都是需要人力运维，导致基本上有多少机器就需要多少人。总之，都不是什么好事情。&lt;/p&gt;
 &lt;p&gt;一些技术比较好的公司，都没有庞大的 SRE 队伍，比如 Instagram, Netflix（现在可能人数不少了），以及一些创业公司，甚至都可以没有专门的 SRE，优秀的 SRE 首先要是开发者，优秀的开发者也离 SRE 不远了。一些耳熟能详的服务，比如 webarchive 这样的数据量，其实  &lt;a href="https://archive.org/details/jonah-edwards-presentation"&gt;背后也只有几个人在维护&lt;/a&gt;。前几年面试了国内的一家公司，在机房遍布全球，业务已经发展的比较庞大（上市了）的时候，SRE 团队也只有 10 个人。&lt;/p&gt;
 &lt;p&gt;另外我比较喜欢问的一个问题是对方关于 AIOps 怎么看。因为我之前搞了两年这个东西，最后得到的结论是，这基本上  &lt;a href="https://www.kawabangga.com/posts/4145"&gt;是个浪费时间、欺骗上层领导的东西&lt;/a&gt;。AI 这东西的不可解释性本质上就和运维操作将就因果相违背的。所以经常喜欢问面试官怎么看这个技术，基本上就可以判断靠不靠谱。当然了，这是我个人的职业阴影导致的后遗症，只能代表个人意见。&lt;/p&gt;
 &lt;p&gt; &lt;/p&gt;
 &lt;p&gt;就说这么多吧，都是一些个人理解，不一定对。写这篇文章感觉自己好像指点江山一样，其实我自己也干了才几年而已，所以本文内容仅供参考。如果有什么问题可以在评论提出，我能回答的话就尽量回答。&lt;/p&gt; &lt;p&gt;The post   &lt;a href="https://www.kawabangga.com/posts/4481"&gt;SRE 的工作介绍&lt;/a&gt; first appeared on   &lt;a href="https://www.kawabangga.com"&gt;卡瓦邦噶！&lt;/a&gt;.&lt;/p&gt; &lt;div&gt;  &lt;h3&gt;相关文章:&lt;/h3&gt;  &lt;ul&gt;   &lt;li&gt;    &lt;a href="https://www.kawabangga.com/posts/3028"&gt;构建大型Cron系统的思考&lt;/a&gt;&lt;/li&gt;   &lt;li&gt;    &lt;a href="https://www.kawabangga.com/posts/2139"&gt;博客维护：速度优化，嵌入instagram&lt;/a&gt;&lt;/li&gt;   &lt;li&gt;    &lt;a href="https://www.kawabangga.com/posts/2210"&gt;Python正则表达式解惑&lt;/a&gt;&lt;/li&gt;   &lt;li&gt;    &lt;a href="https://www.kawabangga.com/blogroll"&gt;申请友链&lt;/a&gt;&lt;/li&gt;   &lt;li&gt;    &lt;a href="https://www.kawabangga.com/db"&gt;DB资料集&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;  &lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>程序开发笔记 Google SRE SRE 工作介绍</category>
      <guid isPermaLink="true">https://itindex.net/detail/61879-sre-%E5%B7%A5%E4%BD%9C</guid>
      <pubDate>Sat, 06 Nov 2021 23:23:03 CST</pubDate>
    </item>
    <item>
      <title>rabbitmq消息去重及防丢失解决方案</title>
      <link>https://itindex.net/detail/61374-rabbitmq-%E6%B6%88%E6%81%AF</link>
      <description>&lt;p&gt;-  &lt;br /&gt;    &lt;/p&gt; &lt;div&gt;&lt;/div&gt; &lt;br /&gt;- &lt;p&gt;&lt;/p&gt; &lt;blockquote&gt;  &lt;p&gt;个人笔记，如有描述不当，欢迎留言指出~&lt;/p&gt;&lt;/blockquote&gt; &lt;h3&gt;  &lt;a href="https://cloudintheking.github.io/#&amp;#21069;&amp;#25552;" title="&amp;#21069;&amp;#25552;"&gt;&lt;/a&gt;前提&lt;/h3&gt; &lt;p&gt;我们知道一个电商项目里时刻都有海量的消息通知，比如顾客注册通知、签到通知、下单通知等等，而我们公司的电商项目更加复杂，包含了客户端、门店端以及供应商端三端，各种各样的消息通知游走在各个服务模块间。如果每个模块都要实现一套消息通知的功能，那无疑是多余的。所以我把各模块的消息功能提取出来独立成一个服务模块，就像一个快递员，把各模块的消息准确投递至各端。  &lt;br /&gt;我采用了自己熟悉的rabbitmq来实现消息功能，  &lt;br /&gt;当模块开发完交差时，组长冷不丁来了句：消息去重以及防丢失机制实现了没？w(ﾟДﾟ)w好吧，赶紧去实现。&lt;/p&gt; &lt;h3&gt;  &lt;a href="https://cloudintheking.github.io/#&amp;#28040;&amp;#24687;&amp;#21435;&amp;#37325;" title="&amp;#28040;&amp;#24687;&amp;#21435;&amp;#37325;"&gt;&lt;/a&gt;消息去重&lt;/h3&gt; &lt;p&gt;  &lt;img alt="@&amp;#28040;&amp;#24687;&amp;#22823;&amp;#33268;&amp;#27969;&amp;#31243;" src="https://fatboa.gz.bcebos.com/img/posts/rabbitmq&amp;#28040;&amp;#24687;&amp;#21435;&amp;#37325;&amp;#21450;&amp;#38450;&amp;#20002;&amp;#22833;&amp;#35299;&amp;#20915;&amp;#26041;&amp;#26696;/1553498886542.png?authorization=bce-auth-v1/b6f23434344c421e8a830ea644d98122/2019-03-26T03:51:19Z/-1/host/3d9448bad08563ec4cdcaa7a17f4d2d0b17e954d1b748645069c61bb445b0942"&gt;&lt;/img&gt;  &lt;br /&gt;依我的经验来看，在消费端去重比较好。因为即使生产端保证投递到rabbitmq上的消息是不重复的，但rabbitmq服务器有可能由于系统或网络原因导致消息重复推送到消费端，所以生产端去重是不可靠的，应当在消费端去重。&lt;/p&gt; &lt;p&gt;怎么解决呢？我的方案是在生产端投递消息的同时，传入correlationId关联id，在消费端接收消息后，从message的messageProperties中拿到correlationId，再根据correlationId从db中查询是否有相关记录。如果有，则说明这条消息已被我们消费过，直接ack，不进行业务处理；没有，那就把消息内容和correlationId存入表中，然后ack。&lt;/p&gt; &lt;blockquote&gt;  &lt;p&gt;这里说明一下，我把消息的接收和业务处理分开来了。消息监听器只负责监听队列消息，并将其存至db中。在另外的任务线程里，从db中取消息记录进去业务处理，如果业务处理中出现异常，结合elasticsearch实现异常报警（这部分还没做，目前还只是记录下错误信息及消息内容）。&lt;/p&gt;&lt;/blockquote&gt; &lt;blockquote&gt;  &lt;p&gt;why?为啥分开处理，其实一开始的设计中消息接收和处理是写在一起的，消息处理成功回复ack，处理异常回复nack。但会有一个严重的问题，但测试环境中，我们发现总有那么几条消息卡在队列里，就因为处理异常回复nack，消息一直在重入队，严重消耗rabbitmq服务器的性能！所以说，大部分异常的消息，都不能指望把消息重推到别的消费端就能处理成功了，所以消息接收和处理分开来是比较好的。&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;方案是有了，但具体代码怎么实现呢？  &lt;br /&gt;生产端关键代码：  &lt;br /&gt;  &lt;table&gt;   &lt;tr&gt;    &lt;td&gt;     &lt;pre&gt;1      &lt;br /&gt;2      &lt;br /&gt;3      &lt;br /&gt;4      &lt;br /&gt;5      &lt;br /&gt;6      &lt;br /&gt;7      &lt;br /&gt;8      &lt;br /&gt;9      &lt;br /&gt;10      &lt;br /&gt;11      &lt;br /&gt;12      &lt;br /&gt;13      &lt;br /&gt;14      &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;    &lt;td&gt;     &lt;pre&gt;public void send(String routingKey, String msg) {      &lt;br /&gt;      RabbitTemplate rabbitTemplate = applicationContext.getBean(&amp;quot;rabbitTemplate&amp;quot;, RabbitTemplate.class);      &lt;br /&gt;      rabbitTemplate.setReturnCallback(this);      &lt;br /&gt;      log.info(&amp;quot;消息发送内容 : &amp;quot; + msg);      &lt;br /&gt;      CorrelationData correlationId = new CorrelationData(UUID.randomUUID().toString());      &lt;br /&gt;      rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -&amp;gt; {      &lt;br /&gt;          if (!ack) {      &lt;br /&gt;              throw new RuntimeException(&amp;quot;send error &amp;quot; + cause);      &lt;br /&gt;          } else {      &lt;br /&gt;              log.info(&amp;quot;send() 消息发送成功 &amp;quot;);      &lt;br /&gt;          }      &lt;br /&gt;      });      &lt;br /&gt;      rabbitTemplate.convertAndSend(&amp;quot;amq.topic&amp;quot;, routingKey, msg, correlationId);      &lt;br /&gt;  }      &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt; &lt;p&gt;我们点开  &lt;code&gt;rabbitTemplate.convertAndSend&lt;/code&gt;方法  &lt;br /&gt;  &lt;table&gt;   &lt;tr&gt;    &lt;td&gt;     &lt;pre&gt;1      &lt;br /&gt;2      &lt;br /&gt;3      &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;    &lt;td&gt;     &lt;pre&gt;public void convertAndSend(String exchange, String routingKey, Object object, CorrelationData correlationData) throws AmqpException {      &lt;br /&gt;      this.send(exchange, routingKey, this.convertMessageIfNecessary(object), correlationData);      &lt;br /&gt;  }      &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt; &lt;p&gt;看到没，convertAndSend方法是以  &lt;code&gt;Object&lt;/code&gt;来接收消息内容，它内部调用的send方法最终还是把Object类转成  &lt;code&gt;Message&lt;/code&gt;类  &lt;br /&gt;  &lt;img alt="@Message.java" src="https://fatboa.gz.bcebos.com/img/posts/rabbitmq&amp;#28040;&amp;#24687;&amp;#21435;&amp;#37325;&amp;#21450;&amp;#38450;&amp;#20002;&amp;#22833;&amp;#35299;&amp;#20915;&amp;#26041;&amp;#26696;/1553502343578.png?authorization=bce-auth-v1/b6f23434344c421e8a830ea644d98122/2019-03-26T03:51:55Z/-1/host/d1ed0e35c9c9fb24cc93e02874fe28debab979be5d1b8d722333ee5d6572202b"&gt;&lt;/img&gt;  &lt;br /&gt;从上图可以看的出，Message包含了  &lt;code&gt;ENCODING&lt;/code&gt;（编码方式）、  &lt;code&gt;SERIALIZER_MESSAGE_CONVERTER&lt;/code&gt;（序列化消息转换器）、  &lt;code&gt;messageProperties&lt;/code&gt;（消息属性）、  &lt;code&gt;body&lt;/code&gt;（消息内容），队列里消息存放着这些东东。  &lt;br /&gt;我们再看看  &lt;strong&gt;MessageProperties&lt;/strong&gt;里放着什么  &lt;br /&gt;  &lt;table&gt;   &lt;tr&gt;    &lt;td&gt;     &lt;pre&gt;1      &lt;br /&gt;2      &lt;br /&gt;3      &lt;br /&gt;4      &lt;br /&gt;5      &lt;br /&gt;6      &lt;br /&gt;7      &lt;br /&gt;8      &lt;br /&gt;9      &lt;br /&gt;10      &lt;br /&gt;11      &lt;br /&gt;12      &lt;br /&gt;13      &lt;br /&gt;14      &lt;br /&gt;15      &lt;br /&gt;16      &lt;br /&gt;17      &lt;br /&gt;18      &lt;br /&gt;19      &lt;br /&gt;20      &lt;br /&gt;21      &lt;br /&gt;22      &lt;br /&gt;23      &lt;br /&gt;24      &lt;br /&gt;25      &lt;br /&gt;26      &lt;br /&gt;27      &lt;br /&gt;28      &lt;br /&gt;29      &lt;br /&gt;30      &lt;br /&gt;31      &lt;br /&gt;32      &lt;br /&gt;33      &lt;br /&gt;34      &lt;br /&gt;35      &lt;br /&gt;36      &lt;br /&gt;37      &lt;br /&gt;38      &lt;br /&gt;39      &lt;br /&gt;40      &lt;br /&gt;41      &lt;br /&gt;42      &lt;br /&gt;43      &lt;br /&gt;44      &lt;br /&gt;45      &lt;br /&gt;46      &lt;br /&gt;47      &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;    &lt;td&gt;     &lt;pre&gt;public class MessageProperties implements Serializable {      &lt;br /&gt;    private static final long serialVersionUID = 1619000546531112290L;      &lt;br /&gt;    public static final String CONTENT_TYPE_BYTES = &amp;quot;application/octet-stream&amp;quot;;      &lt;br /&gt;    public static final String CONTENT_TYPE_TEXT_PLAIN = &amp;quot;text/plain&amp;quot;;      &lt;br /&gt;    public static final String CONTENT_TYPE_SERIALIZED_OBJECT = &amp;quot;application/x-java-serialized-object&amp;quot;;      &lt;br /&gt;    public static final String CONTENT_TYPE_JSON = &amp;quot;application/json&amp;quot;;      &lt;br /&gt;    public static final String CONTENT_TYPE_JSON_ALT = &amp;quot;text/x-json&amp;quot;;      &lt;br /&gt;    public static final String CONTENT_TYPE_XML = &amp;quot;application/xml&amp;quot;;      &lt;br /&gt;    public static final String SPRING_BATCH_FORMAT = &amp;quot;springBatchFormat&amp;quot;;      &lt;br /&gt;    public static final String BATCH_FORMAT_LENGTH_HEADER4 = &amp;quot;lengthHeader4&amp;quot;;      &lt;br /&gt;    public static final String SPRING_AUTO_DECOMPRESS = &amp;quot;springAutoDecompress&amp;quot;;      &lt;br /&gt;    public static final String X_DELAY = &amp;quot;x-delay&amp;quot;;      &lt;br /&gt;    public static final String DEFAULT_CONTENT_TYPE = &amp;quot;application/octet-stream&amp;quot;;      &lt;br /&gt;    public static final MessageDeliveryMode DEFAULT_DELIVERY_MODE;      &lt;br /&gt;    public static final Integer DEFAULT_PRIORITY;      &lt;br /&gt;    private final Map&amp;lt;String, Object&amp;gt; headers = new HashMap();      &lt;br /&gt;    private volatile Date timestamp;      &lt;br /&gt;    private volatile String messageId;      &lt;br /&gt;    private volatile String userId;      &lt;br /&gt;    private volatile String appId;      &lt;br /&gt;    private volatile String clusterId;      &lt;br /&gt;    private volatile String type;      &lt;br /&gt;    private volatile String correlationId;      &lt;br /&gt;    private volatile String replyTo;      &lt;br /&gt;    private volatile String contentType = &amp;quot;application/octet-stream&amp;quot;;      &lt;br /&gt;    private volatile String contentEncoding;      &lt;br /&gt;    private volatile long contentLength;      &lt;br /&gt;    private volatile boolean contentLengthSet;      &lt;br /&gt;    private volatile MessageDeliveryMode deliveryMode;      &lt;br /&gt;    private volatile String expiration;      &lt;br /&gt;    private volatile Integer priority;      &lt;br /&gt;    private volatile Boolean redelivered;      &lt;br /&gt;    private volatile String receivedExchange;      &lt;br /&gt;    private volatile String receivedRoutingKey;      &lt;br /&gt;    private volatile String receivedUserId;      &lt;br /&gt;    private volatile long deliveryTag;      &lt;br /&gt;    private volatile boolean deliveryTagSet;      &lt;br /&gt;    private volatile Integer messageCount;      &lt;br /&gt;    private volatile String consumerTag;      &lt;br /&gt;    private volatile String consumerQueue;      &lt;br /&gt;    private volatile Integer receivedDelay;      &lt;br /&gt;    private volatile MessageDeliveryMode receivedDeliveryMode;      &lt;br /&gt;    private volatile boolean finalRetryForMessageWithNoId;      &lt;br /&gt;    private transient volatile Type inferredArgumentType;      &lt;br /&gt;    private transient volatile Method targetMethod;      &lt;br /&gt;    private transient volatile Object targetBean;      &lt;br /&gt;}      &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt; &lt;p&gt;果然  &lt;code&gt;correlationId&lt;/code&gt;就在这里，然后看到这里我就没继续深入了，原以为rabbitTemplate.convertAndSend方法会自动将correlationId放入messageProperties中，结果表明我错了。在消费端拿到的correlationId为  &lt;code&gt;null&lt;/code&gt;。也就是说，convertAndSend方法里correlationId根本就没有被放进去的，大家感兴趣的话可以看看源码，这里就不说了。&lt;/p&gt; &lt;p&gt;问题找出来就好办了  &lt;br /&gt;  &lt;table&gt;   &lt;tr&gt;    &lt;td&gt;     &lt;pre&gt;1      &lt;br /&gt;2      &lt;br /&gt;3      &lt;br /&gt;4      &lt;br /&gt;5      &lt;br /&gt;6      &lt;br /&gt;7      &lt;br /&gt;8      &lt;br /&gt;9      &lt;br /&gt;10      &lt;br /&gt;11      &lt;br /&gt;12      &lt;br /&gt;13      &lt;br /&gt;14      &lt;br /&gt;15      &lt;br /&gt;16      &lt;br /&gt;17      &lt;br /&gt;18      &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;    &lt;td&gt;     &lt;pre&gt;public void send(String routingKey, String msg) {      &lt;br /&gt;      RabbitTemplate rabbitTemplate = applicationContext.getBean(&amp;quot;rabbitTemplate&amp;quot;, RabbitTemplate.class);      &lt;br /&gt;      rabbitTemplate.setReturnCallback(this);      &lt;br /&gt;      log.info(&amp;quot;消息发送内容 : &amp;quot; + msg);      &lt;br /&gt;      CorrelationData correlationId = new CorrelationData(UUID.randomUUID().toString());      &lt;br /&gt;      rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -&amp;gt; {      &lt;br /&gt;          if (!ack) {      &lt;br /&gt;              throw new RuntimeException(&amp;quot;send error &amp;quot; + cause);      &lt;br /&gt;          } else {      &lt;br /&gt;              log.info(&amp;quot;send() 消息发送成功 &amp;quot;);      &lt;br /&gt;          }      &lt;br /&gt;      });      &lt;br /&gt;      Message message = MessageBuilder.withBody(msg.getBytes())      &lt;br /&gt;              .setContentType(MessageProperties.CONTENT_TYPE_TEXT_PLAIN)      &lt;br /&gt;              .setCorrelationId(correlationId.toString())      &lt;br /&gt;              .build();      &lt;br /&gt;      rabbitTemplate.convertAndSend(&amp;quot;amq.topic&amp;quot;, routingKey, message, correlationId);      &lt;br /&gt;  }      &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt; &lt;p&gt;直接构建Message类，手动传入correlationId总行了吧。在消费端从Message里拿到correlationId，再从db查询就行了。好了，到这里去重机制就实现了&lt;/p&gt; &lt;h3&gt;  &lt;a href="https://cloudintheking.github.io/#&amp;#28040;&amp;#24687;&amp;#38450;&amp;#20002;&amp;#22833;" title="&amp;#28040;&amp;#24687;&amp;#38450;&amp;#20002;&amp;#22833;"&gt;&lt;/a&gt;消息防丢失&lt;/h3&gt; &lt;p&gt;rabbitmq是支持队列、消息的持久化的。即便rabbitmq突然挂了，那些尚在队列未能推送的消息在rabbitmq重启后也是能够继续推送的，所以丢失问题一般不出现在rabbitmq上。&lt;/p&gt; &lt;p&gt;rabbitmq将消息从队列推到消费端后，需要有一个回应告诉它队列里的这条消息的去留。主要有两种方式：&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;auto: 自动回应，消息在发送给消费端后立即确认&lt;/li&gt;  &lt;li&gt;manual 手动回应，消息消费正常后由消费端返回ack;或消费异常返回nack,将消息重入队；或返回reject,丢弃该条消息&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;  &lt;strong&gt;   &lt;em&gt;springboot的yaml配置&lt;/em&gt;&lt;/strong&gt;  &lt;br /&gt;  &lt;table&gt;   &lt;tr&gt;    &lt;td&gt;     &lt;pre&gt;1      &lt;br /&gt;2      &lt;br /&gt;3      &lt;br /&gt;4      &lt;br /&gt;5      &lt;br /&gt;6      &lt;br /&gt;7      &lt;br /&gt;8      &lt;br /&gt;9      &lt;br /&gt;10      &lt;br /&gt;11      &lt;br /&gt;12      &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;    &lt;td&gt;     &lt;pre&gt;rabbitmq:      &lt;br /&gt;   host: 127.0.0.1      &lt;br /&gt;   port: 5672      &lt;br /&gt;   username: admin      &lt;br /&gt;   password: admin      &lt;br /&gt;   publisher-confirms: true #开启confirmcallback      &lt;br /&gt;   publisher-returns: true #开启returncallback      &lt;br /&gt;   listener:      &lt;br /&gt;     simple:      &lt;br /&gt;       acknowledge-mode: manual      &lt;br /&gt;     direct:      &lt;br /&gt;       acknowledge-mode: MANUAL      &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt; &lt;p&gt;另外，如果消息在消费的时候，消费端与rabbitmq的连接中断了，那这条消息会被重新放回队列进行推送，这个时候我们的去重机制就起作用了；如果消费的时候，消费端死机了，长时间不回应rabbitmq，这时候我们可以将该消息转至死信队列，防止原队列阻塞。死信队列，这里也不做介绍，有兴趣百度呗。  &lt;br /&gt;所以消费端出现消息丢失的可能性也不大，问题就可能出在生产端。看看下面这张图  &lt;br /&gt;  &lt;img alt="@&amp;#26469;&amp;#28304;&amp;#20110;&amp;#32593;&amp;#32476;" src="https://fatboa.gz.bcebos.com/img/posts/rabbitmq&amp;#28040;&amp;#24687;&amp;#21435;&amp;#37325;&amp;#21450;&amp;#38450;&amp;#20002;&amp;#22833;&amp;#35299;&amp;#20915;&amp;#26041;&amp;#26696;/1553504804445.png?authorization=bce-auth-v1/b6f23434344c421e8a830ea644d98122/2019-03-26T03:53:09Z/-1/host/09aeca4e5e399a3fefcf467a3bb5eed2f3154ca506790cf53590402c8ae71575"&gt;&lt;/img&gt;  &lt;br /&gt;左边P代表生产端，中间是rabbitmq，右边是消费端，绿色的X是交换机，红色的是队列，用过rabbitmq的小伙伴肯定一目了然了。&lt;/p&gt; &lt;p&gt;rabbitmq 整个消息投递的路径为：  &lt;br /&gt;  &lt;code&gt;producer&lt;/code&gt;-&amp;gt;  &lt;code&gt;rabbitmq broker cluster&lt;/code&gt;-&amp;gt;  &lt;code&gt;exchange&lt;/code&gt;-&amp;gt;  &lt;code&gt;queue&lt;/code&gt;-&amp;gt;  &lt;code&gt;consumer&lt;/code&gt;&lt;/p&gt; &lt;p&gt;生产端投递消息到rabbitmq里，rabbitmq将消息发到交换机中，交换机再根据路由键将消息最终送到队列中，队列取出消息推送到消费端。只有最终抵达队列的消息才是可靠的，不会丢失。所以我们要实现的就是保证生产端的消息务必推送到rabbitmq的队列中。&lt;/p&gt; &lt;p&gt;那么生产端是怎么知道自己的消费准确投递到了队列中呢？rabbitmq返回了两个回调给生产端。&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;message 从 producer 到 rabbitmq broker cluster 则会返回一个    &lt;code&gt;confirmCallback&lt;/code&gt; &lt;/li&gt;  &lt;li&gt;message 从 exchange-&amp;gt;queue 投递失败则会返回一个    &lt;code&gt;returnCallback&lt;/code&gt; 。我们将利用这两个 callback 控制消息的最终一致性和部分纠错能力。&lt;/li&gt;&lt;/ul&gt; &lt;h4&gt;  &lt;a href="https://cloudintheking.github.io/#&amp;#35299;&amp;#20915;&amp;#26041;&amp;#26696;" title="&amp;#35299;&amp;#20915;&amp;#26041;&amp;#26696;"&gt;&lt;/a&gt;解决方案&lt;/h4&gt; &lt;p&gt;生产端在投递消息前，先将消息内容、投递状态、重试次数记录在db中，然后在两个回调中修改记录状态。另外再开一个任务线程去取db中记录的失败消息，进行重新投递。&lt;/p&gt; &lt;h4&gt;  &lt;a href="https://cloudintheking.github.io/#&amp;#20195;&amp;#30721;&amp;#23454;&amp;#29616;" title="&amp;#20195;&amp;#30721;&amp;#23454;&amp;#29616;"&gt;&lt;/a&gt;代码实现&lt;/h4&gt; &lt;p&gt;  &lt;strong&gt;   &lt;em&gt;失败消息记录实体类：&lt;/em&gt;&lt;/strong&gt;  &lt;br /&gt;  &lt;table&gt;   &lt;tr&gt;    &lt;td&gt;     &lt;pre&gt;1      &lt;br /&gt;2      &lt;br /&gt;3      &lt;br /&gt;4      &lt;br /&gt;5      &lt;br /&gt;6      &lt;br /&gt;7      &lt;br /&gt;8      &lt;br /&gt;9      &lt;br /&gt;10      &lt;br /&gt;11      &lt;br /&gt;12      &lt;br /&gt;13      &lt;br /&gt;14      &lt;br /&gt;15      &lt;br /&gt;16      &lt;br /&gt;17      &lt;br /&gt;18      &lt;br /&gt;19      &lt;br /&gt;20      &lt;br /&gt;21      &lt;br /&gt;22      &lt;br /&gt;23      &lt;br /&gt;24      &lt;br /&gt;25      &lt;br /&gt;26      &lt;br /&gt;27      &lt;br /&gt;28      &lt;br /&gt;29      &lt;br /&gt;30      &lt;br /&gt;31      &lt;br /&gt;32      &lt;br /&gt;33      &lt;br /&gt;34      &lt;br /&gt;35      &lt;br /&gt;36      &lt;br /&gt;37      &lt;br /&gt;38      &lt;br /&gt;39      &lt;br /&gt;40      &lt;br /&gt;41      &lt;br /&gt;42      &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;    &lt;td&gt;     &lt;pre&gt;/**      &lt;br /&gt; * @time: 2019/2/18 9:14      &lt;br /&gt; * @author: hl      &lt;br /&gt; * @descripe: 失败消息记录      &lt;br /&gt; * @version: 1.0      &lt;br /&gt; */      &lt;br /&gt;Entity      &lt;br /&gt;@Table(name = &amp;quot;t_failure_mq_record&amp;quot;)      &lt;br /&gt;@Data      &lt;br /&gt;@NoArgsConstructor      &lt;br /&gt;@EntityListeners(AuditingEntityListener.class)      &lt;br /&gt;public class FailureMqRecord extends Uuid {      &lt;br /&gt;    /**      &lt;br /&gt;     * 失败消息内容      &lt;br /&gt;     */      &lt;br /&gt;    private String message;      &lt;br /&gt;    /**      &lt;br /&gt;     * 重试次数      &lt;br /&gt;     */      &lt;br /&gt;    @Column(name = &amp;quot;retry_time&amp;quot;)      &lt;br /&gt;    private Integer retryTime;      &lt;br /&gt;      &lt;br /&gt;    /**      &lt;br /&gt;     * 消息状态 1:投递成功 2：投递失败      &lt;br /&gt;     */      &lt;br /&gt;    private Integer status;      &lt;br /&gt;      &lt;br /&gt;    /**      &lt;br /&gt;     * 关联id      &lt;br /&gt;     */      &lt;br /&gt;    private String correlationId;      &lt;br /&gt;    /**      &lt;br /&gt;     * 创建时间      &lt;br /&gt;     */      &lt;br /&gt;    @CreatedDate      &lt;br /&gt;    @Column(name = &amp;quot;create_time&amp;quot;, updatable = false)      &lt;br /&gt;    private Date createTime;      &lt;br /&gt;      &lt;br /&gt;    public FailureMqRecord(String message) {      &lt;br /&gt;        this.message = message;      &lt;br /&gt;    }      &lt;br /&gt;}      &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt; &lt;p&gt;  &lt;strong&gt;   &lt;em&gt;rabbitmq发送器：&lt;/em&gt;&lt;/strong&gt;  &lt;br /&gt;  &lt;table&gt;   &lt;tr&gt;    &lt;td&gt;     &lt;pre&gt;1      &lt;br /&gt;2      &lt;br /&gt;3      &lt;br /&gt;4      &lt;br /&gt;5      &lt;br /&gt;6      &lt;br /&gt;7      &lt;br /&gt;8      &lt;br /&gt;9      &lt;br /&gt;10      &lt;br /&gt;11      &lt;br /&gt;12      &lt;br /&gt;13      &lt;br /&gt;14      &lt;br /&gt;15      &lt;br /&gt;16      &lt;br /&gt;17      &lt;br /&gt;18      &lt;br /&gt;19      &lt;br /&gt;20      &lt;br /&gt;21      &lt;br /&gt;22      &lt;br /&gt;23      &lt;br /&gt;24      &lt;br /&gt;25      &lt;br /&gt;26      &lt;br /&gt;27      &lt;br /&gt;28      &lt;br /&gt;29      &lt;br /&gt;30      &lt;br /&gt;31      &lt;br /&gt;32      &lt;br /&gt;33      &lt;br /&gt;34      &lt;br /&gt;35      &lt;br /&gt;36      &lt;br /&gt;37      &lt;br /&gt;38      &lt;br /&gt;39      &lt;br /&gt;40      &lt;br /&gt;41      &lt;br /&gt;42      &lt;br /&gt;43      &lt;br /&gt;44      &lt;br /&gt;45      &lt;br /&gt;46      &lt;br /&gt;47      &lt;br /&gt;48      &lt;br /&gt;49      &lt;br /&gt;50      &lt;br /&gt;51      &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;    &lt;td&gt;     &lt;pre&gt;/**      &lt;br /&gt; * @time: 2019/2/13 9:47      &lt;br /&gt; * @author: hl      &lt;br /&gt; * @descripe:      &lt;br /&gt; * @version: 1.0      &lt;br /&gt; */      &lt;br /&gt;@Component      &lt;br /&gt;@Slf4j      &lt;br /&gt;public class RabbitMqSender implements RabbitTemplate.ReturnCallback {      &lt;br /&gt;    @Autowired      &lt;br /&gt;    private ApplicationContext applicationContext;      &lt;br /&gt;    @Autowired      &lt;br /&gt;    private FailureMqRecordRepository failureMqRecordRepository;      &lt;br /&gt;      &lt;br /&gt;    public void send(String routingKey, FailureMqRecord failureMqRecord) {      &lt;br /&gt;        RabbitTemplate rabbitTemplate = applicationContext.getBean(&amp;quot;rabbitTemplate&amp;quot;, RabbitTemplate.class);      &lt;br /&gt;        //设置当前实例为rabbitmqtemplate的returncallback      &lt;br /&gt;        rabbitTemplate.setReturnCallback(this);      &lt;br /&gt;        rabbitTemplate.setConfirmCallback(((correlationData1, ack, cause) -&amp;gt; {      &lt;br /&gt;            if (!ack) { //投递至broker失败      &lt;br /&gt;                failureMqRecord.setStatus(2);//设为投递失败      &lt;br /&gt;                failureMqRecordRepository.save(failureMqRecord);      &lt;br /&gt;            }      &lt;br /&gt;        }));      &lt;br /&gt;        Message message = MessageBuilder.withBody(failureMqRecord.getMessage().getBytes())      &lt;br /&gt;                .setContentType(MessageProperties.CONTENT_TYPE_TEXT_PLAIN)      &lt;br /&gt;                .setCorrelationId(failureMqRecord.getCorrelationId())      &lt;br /&gt;                .build();      &lt;br /&gt;        rabbitTemplate.convertAndSend(&amp;quot;amq.topic&amp;quot;, routingKey, message, new CorrelationData(failureMqRecord.getCorrelationId()));      &lt;br /&gt;        failureMqRecord.setStatus(1);//设为投递成功      &lt;br /&gt;        failureMqRecord.setRetryTime(failureMqRecord.getRetryTime() + 1);//重试次数+1      &lt;br /&gt;        failureMqRecordRepository.save(failureMqRecord);      &lt;br /&gt;    }      &lt;br /&gt;      &lt;br /&gt;    /**      &lt;br /&gt;     * 消息由exchang未能正确投递到queue时触发回调      &lt;br /&gt;     *      &lt;br /&gt;     * @param message      &lt;br /&gt;     * @param replyCode      &lt;br /&gt;     * @param replyText      &lt;br /&gt;     * @param exchange      &lt;br /&gt;     * @param routingKey      &lt;br /&gt;     */      &lt;br /&gt;    @Override      &lt;br /&gt;    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) throws BusinessException {      &lt;br /&gt;        FailureMqRecord mq = failureMqRecordRepository.findByCorrelationId(message.getMessageProperties().getCorrelationId());      &lt;br /&gt;        mq.setStatus(2);      &lt;br /&gt;        failureMqRecordRepository.save(mq);      &lt;br /&gt;        log.error(&amp;quot;审批消息：{} 投递至路由：{}失败&amp;quot;, message.getBody(), routingKey);      &lt;br /&gt;    }      &lt;br /&gt;}      &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt; &lt;p&gt;  &lt;strong&gt;   &lt;em&gt;任务线程，实现消息重试机制：&lt;/em&gt;&lt;/strong&gt;  &lt;br /&gt;  &lt;table&gt;   &lt;tr&gt;    &lt;td&gt;     &lt;pre&gt;1      &lt;br /&gt;2      &lt;br /&gt;3      &lt;br /&gt;4      &lt;br /&gt;5      &lt;br /&gt;6      &lt;br /&gt;7      &lt;br /&gt;8      &lt;br /&gt;9      &lt;br /&gt;10      &lt;br /&gt;11      &lt;br /&gt;12      &lt;br /&gt;13      &lt;br /&gt;14      &lt;br /&gt;15      &lt;br /&gt;16      &lt;br /&gt;17      &lt;br /&gt;18      &lt;br /&gt;19      &lt;br /&gt;20      &lt;br /&gt;21      &lt;br /&gt;22      &lt;br /&gt;23      &lt;br /&gt;24      &lt;br /&gt;25      &lt;br /&gt;26      &lt;br /&gt;27      &lt;br /&gt;28      &lt;br /&gt;29      &lt;br /&gt;30      &lt;br /&gt;31      &lt;br /&gt;32      &lt;br /&gt;33      &lt;br /&gt;34      &lt;br /&gt;35      &lt;br /&gt;36      &lt;br /&gt;37      &lt;br /&gt;38      &lt;br /&gt;39      &lt;br /&gt;40      &lt;br /&gt;41      &lt;br /&gt;42      &lt;br /&gt;43      &lt;br /&gt;44      &lt;br /&gt;45      &lt;br /&gt;46      &lt;br /&gt;47      &lt;br /&gt;48      &lt;br /&gt;49      &lt;br /&gt;50      &lt;br /&gt;51      &lt;br /&gt;52      &lt;br /&gt;53      &lt;br /&gt;54      &lt;br /&gt;55      &lt;br /&gt;56      &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;    &lt;td&gt;     &lt;pre&gt;/**      &lt;br /&gt; * @time: 2019/2/18 10:10      &lt;br /&gt; * @author: huanglong      &lt;br /&gt; * @descripe: 消息重发定时器      &lt;br /&gt; * @version: 1.0      &lt;br /&gt; */      &lt;br /&gt;@Component      &lt;br /&gt;@Slf4j      &lt;br /&gt;public class MqScheduler {      &lt;br /&gt;    @Autowired      &lt;br /&gt;    private RabbitMqSender rabbitMqSender;      &lt;br /&gt;    @Autowired      &lt;br /&gt;    private ApprovalMqRepository failureMqRecordRepository;      &lt;br /&gt;    @Autowired      &lt;br /&gt;    private RedisDistributedLock redisDistributedLock;      &lt;br /&gt;      &lt;br /&gt;    /**      &lt;br /&gt;     * 每3分钟执行一次      &lt;br /&gt;     * 将投递失败消息重新投递到rabbitmq      &lt;br /&gt;     */      &lt;br /&gt;    @Scheduled(cron = &amp;quot;* */3 * * * ?&amp;quot;)      &lt;br /&gt;    void push() {      &lt;br /&gt;        List&amp;lt;FailureMqRecord&amp;gt; failureMqRecords = failureMqRecordRepository.findAll()      &lt;br /&gt;                .stream()      &lt;br /&gt;                .filter(failureMqRecord -&amp;gt; {      &lt;br /&gt;                    if (failureMqRecord.getRetryTime() == 3) {      &lt;br /&gt;                        log.error(&amp;quot;警告！该消息已重投3次失败，请人工处理，消息记录uuid:{}&amp;quot;, failureMqRecord.getUuid());      &lt;br /&gt;                    }      &lt;br /&gt;                    //过滤出重试次数不超过3次、状态为2的消息记录      &lt;br /&gt;                    if (failureMqRecord.getRetryTime() &amp;lt; 3 &amp;amp;&amp;amp; failureMqRecord.getStatus() == 0) {      &lt;br /&gt;                        return true;      &lt;br /&gt;                    }      &lt;br /&gt;                    return false;      &lt;br /&gt;                })      &lt;br /&gt;                .collect(Collectors.toList());      &lt;br /&gt;      &lt;br /&gt;        Iterator&amp;lt;FailureMqRecord&amp;gt; mqIterator = failureMqRecords.iterator();      &lt;br /&gt;        while (mqIterator.hasNext()) {      &lt;br /&gt;            FailureMqRecord failureMqRecord = mqIterator.next();      &lt;br /&gt;            //获取,过期时间5秒，不重复获取      &lt;br /&gt;            if (redisDistributedLock.lock(failureMqRecord.getUuid(), 5000L, 0, 1000L)) {      &lt;br /&gt;                // 因为有可能上一个线程刚释放该记录的锁，就被当前先线程获取到该记录的锁，导致记录已被      &lt;br /&gt;                FailureMqRecord failurelatest = failureMqRecordRepository.findById(failureMqRecord.getUuid()).orElse(null);      &lt;br /&gt;                ApprovalPushMessage pushMessage = JSON.parseObject(failurelatest.getMessage(), ApprovalPushMessage.class);      &lt;br /&gt;                //当前时间距离该记录最近一次修改时间的间隔，防止上个线程重试过后，当前线程又重试一次      &lt;br /&gt;                long lastUpdatePeriod = System.currentTimeMillis() - failurelatest.getUpdateTime().getTime(); //距离上次更新间隔      &lt;br /&gt;                //重判断记录是否符合条件,重试次数小于3、状态为投递失败、距离上次重试不能少于2分钟      &lt;br /&gt;                if (failurelatest.getRetryTime() &amp;lt; 3 &amp;amp;&amp;amp; failurelatest.getStatus() == 2 &amp;amp;&amp;amp; lastUpdatePeriod &amp;gt; 2 * 60 * 1000) {      &lt;br /&gt;                    rabbitMqSender.send(&amp;quot;approval.create&amp;quot;, failureMqRecord);      &lt;br /&gt;                }      &lt;br /&gt;                //释放      &lt;br /&gt;                redisDistributedLock.releaseLock(failureMqRecord.getUuid());      &lt;br /&gt;            }      &lt;br /&gt;        }      &lt;br /&gt;    }      &lt;br /&gt;}      &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt; &lt;p&gt;聪明的小伙伴看到这里，会发现任务线程里还用到了分布式。为啥还要加分布式锁，因为是分布式架构啊，会有多个相同定时器从db里取记录处理，如果不加分布式锁，那真的要乱套了。因为redis用的多，就用redis来实现分布式锁了，zookeeper啥的，有空再研究了。redis分布式锁的代码实现，网上有很多资源，我这里就不贴了，嘿嘿&lt;/p&gt; &lt;p&gt;好了，到这里rabbitmq的去重以及防丢失方案已经实现了，如果你有更好的解决方案或者指出我方案的不足，欢迎留言讨论&lt;/p&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>后端笔记 rabbitmq</category>
      <guid isPermaLink="true">https://itindex.net/detail/61374-rabbitmq-%E6%B6%88%E6%81%AF</guid>
      <pubDate>Fri, 22 Mar 2019 11:38:54 CST</pubDate>
    </item>
    <item>
      <title>常见分布式应用系统设计图解（十二）：证券交易系统</title>
      <link>https://itindex.net/detail/61117-%E5%B8%B8%E8%A7%81-%E5%88%86%E5%B8%83-%E5%BA%94%E7%94%A8</link>
      <description>&lt;p&gt;这篇讲的是证券交易系统，这类系统包含的内容很多，但是我们还是把目光放在核心的交易部分，比如说股票交易。在某个可交易时间，如果卖家 A 要以至少 y 的价格卖掉股票 x，卖家 B 愿以至多 y 的价格买入股票 x，那么这个交易就可以发生。&lt;/p&gt;



 &lt;p&gt;虽说是交易系统，但是它和任何一个支付平台的交易系统有着显著的不同，它的核心是一个竞价匹配的机制，而非货币支付的机制，简单地说，这个机制包含了这样四个步骤：&lt;/p&gt;



 &lt;ul&gt;  &lt;li&gt;挂单（可以是买单，也可以是卖单）&lt;/li&gt;  &lt;li&gt;匹配（或者叫做撮合）&lt;/li&gt;  &lt;li&gt;成交&lt;/li&gt;  &lt;li&gt;清算&lt;/li&gt;&lt;/ul&gt;



 &lt;p&gt;从非功能的角度看，有这样几条需求是这样的系统尤其要强调的：&lt;/p&gt;



 &lt;ul&gt;  &lt;li&gt;Consistency，从单个交易的角度来说，主要就是事务性，这是交易系统最最基本的要求。系统不能用了是个灾难，但是如果交易数据错误了这就是个大得多的灾难。&lt;/li&gt;  &lt;li&gt;Durability，交易数据必须要持久化。&lt;/li&gt;  &lt;li&gt;Throughput，很多股票市场都是对全球开放的，吞吐量意味着对于交易高峰的接纳能力。&lt;/li&gt;  &lt;li&gt;Latency，和吞吐量关系密切，可以放在一起讨论。大型交易系统的延迟的最小单位都是   &lt;a href="https://www.nasdaq.com/solutions/trading-and-matching-technology" rel="noreferrer noopener" target="_blank"&gt;按微秒论&lt;/a&gt;的。从架构上看这类系统具备一些异步系统（比如下单支付系统）的特点，但是低延迟的要求决定了它的处理方式明显不同。&lt;/li&gt;&lt;/ul&gt;



 &lt;img alt="" src="https://www.raychase.net/wp-content/uploads/2020/12/Security-Trading-1.png"&gt;&lt;/img&gt;



 &lt;ul&gt;  &lt;li&gt;整个系统来看，包括挂单、匹配、交易和查询这样几个部分。实线部分表示的是写或读写操作，虚线是读操作。&lt;/li&gt;  &lt;li&gt;假设有卖家和买家两个用户，分别在不同的时间提交了挂单请求，一个是卖单，一个是买单。&lt;/li&gt;  &lt;li&gt;鉴权分为两个部分来完成，基础的部分由 API Gateway 来完成。&lt;/li&gt;  &lt;li&gt;Exchange Server 收到原始挂单请求以后，首先调用 Sequencer 去获取一个时间戳，也包括一个基于时间戳生成的 ID。这个时间戳非常重要，因为交易的逻辑里面，对于买单卖单的匹配，以及同价单的优先级，都要基于时间戳的规则来进行。时间戳不能仅仅基于 Exchange Server 自己的时钟来进行，因为每台机器的时钟很可能都不一样。&lt;/li&gt;  &lt;li&gt;对于买单，查询账户系统并扣住保证金。&lt;/li&gt;  &lt;li&gt;将买单或卖单放入指定的队列，不同的股票有不同的队列来维护。这个队列本身是一个优先级队列，从宏观上看就是 order book。对于买单来说，买价越高越靠前；对于卖单来说，卖价越低越靠前。&lt;/li&gt;  &lt;li&gt;不同队列的变更会被 router 通知到不同的匹配（撮合）引擎，这里有多个不同的引擎，每个引擎关注不同的队列变更。在每个引擎的内存中维护一个队列中靠近队列出口的买卖单集合，也是以优先级队列的形式维护在内存中（具体实现可以是堆）。&lt;/li&gt;  &lt;li&gt;这样迅速的匹配就可以在内存中迅速发生并完成，内存的数据结构以 Snapshot + WHL 的方式持久化，以达到效率和状态不丢失的平衡。&lt;/li&gt;  &lt;li&gt;如果这台机器崩溃，还有集群中的备用机可以顶上，并从上述的 Snapshot + WHL 中恢复之前的状态。这些机器都通过 Node Manager（比如 Zookeeper）来管理。&lt;/li&gt;  &lt;li&gt;每次匹配完成，都有一个事件加入到 exchange 的队列中，每只股票都有自己的 exchange 队列。&lt;/li&gt;  &lt;li&gt;Router 将队列的事件通知到相应的支付系统和 Tick Calculator。支付系统（或者是清算系统）会完成用户扣款或打款的操作，而 Tick Calculator 会根据交易信息改变当前的股价并持久化到数据库中（这里的数据库需要较大的吞吐量，可以根据股票种类+时间序做 sharding）。&lt;/li&gt;  &lt;li&gt;用户可以查询自己的账户变更状况，用户也可以通过 Quotation 系统查询股价变更状况。&lt;/li&gt;&lt;/ul&gt;



 &lt;p&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;文章未经特殊标明皆为本人原创，未经许可不得用于任何商业用途，转载请保持完整性并注明来源链接    &lt;a href="https://www.raychase.net/6453"&gt;《四火的唠叨》&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;div&gt;
  &lt;p&gt;你可能也喜欢看：&lt;/p&gt;  &lt;ol&gt;
   &lt;li&gt;    &lt;a href="https://www.raychase.net/6275" rel="bookmark" title="&amp;#24120;&amp;#35265;&amp;#20998;&amp;#24067;&amp;#24335;&amp;#24212;&amp;#29992;&amp;#31995;&amp;#32479;&amp;#35774;&amp;#35745;&amp;#22270;&amp;#35299;&amp;#65288;&amp;#19977;&amp;#65289;&amp;#65306;Top K &amp;#31995;&amp;#32479;"&gt;常见分布式应用系统设计图解（三）：Top K 系统 &lt;/a&gt;&lt;/li&gt;
   &lt;li&gt;    &lt;a href="https://www.raychase.net/6299" rel="bookmark" title="&amp;#24120;&amp;#35265;&amp;#20998;&amp;#24067;&amp;#24335;&amp;#24212;&amp;#29992;&amp;#31995;&amp;#32479;&amp;#35774;&amp;#35745;&amp;#22270;&amp;#35299;&amp;#65288;&amp;#22235;&amp;#65289;&amp;#65306;&amp;#36755;&amp;#20837;&amp;#24314;&amp;#35758;&amp;#31995;&amp;#32479;"&gt;常见分布式应用系统设计图解（四）：输入建议系统 &lt;/a&gt;&lt;/li&gt;
   &lt;li&gt;    &lt;a href="https://www.raychase.net/6312" rel="bookmark" title="&amp;#24120;&amp;#35265;&amp;#20998;&amp;#24067;&amp;#24335;&amp;#24212;&amp;#29992;&amp;#31995;&amp;#32479;&amp;#35774;&amp;#35745;&amp;#22270;&amp;#35299;&amp;#65288;&amp;#20116;&amp;#65289;&amp;#65306;Proximity &amp;#31995;&amp;#32479;"&gt;常见分布式应用系统设计图解（五）：Proximity 系统 &lt;/a&gt;&lt;/li&gt;
   &lt;li&gt;    &lt;a href="https://www.raychase.net/6429" rel="bookmark" title="&amp;#24120;&amp;#35265;&amp;#20998;&amp;#24067;&amp;#24335;&amp;#24212;&amp;#29992;&amp;#31995;&amp;#32479;&amp;#35774;&amp;#35745;&amp;#22270;&amp;#35299;&amp;#65288;&amp;#20061;&amp;#65289;&amp;#65306;&amp;#21327;&amp;#21516;&amp;#32534;&amp;#36753;&amp;#31995;&amp;#32479;"&gt;常见分布式应用系统设计图解（九）：协同编辑系统 &lt;/a&gt;&lt;/li&gt;
   &lt;li&gt;    &lt;a href="https://www.raychase.net/6434" rel="bookmark" title="&amp;#24120;&amp;#35265;&amp;#20998;&amp;#24067;&amp;#24335;&amp;#24212;&amp;#29992;&amp;#31995;&amp;#32479;&amp;#35774;&amp;#35745;&amp;#22270;&amp;#35299;&amp;#65288;&amp;#21313;&amp;#65289;&amp;#65306;&amp;#30005;&amp;#21830;&amp;#31186;&amp;#26432;&amp;#31995;&amp;#32479;"&gt;常见分布式应用系统设计图解（十）：电商秒杀系统 &lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>System and Architecture 交易系统 图解笔记 应用系统 系统设计</category>
      <guid isPermaLink="true">https://itindex.net/detail/61117-%E5%B8%B8%E8%A7%81-%E5%88%86%E5%B8%83-%E5%BA%94%E7%94%A8</guid>
      <pubDate>Sun, 27 Dec 2020 02:09:00 CST</pubDate>
    </item>
    <item>
      <title>rabbitmq消息去重及防丢失解决方案</title>
      <link>https://itindex.net/detail/59929-rabbitmq-%E6%B6%88%E6%81%AF</link>
      <description>&lt;p&gt;-  &lt;br /&gt;    &lt;/p&gt; &lt;div&gt;&lt;/div&gt; &lt;br /&gt;- &lt;p&gt;&lt;/p&gt; &lt;blockquote&gt;  &lt;p&gt;个人笔记，如有描述不当，欢迎留言指出~&lt;/p&gt;&lt;/blockquote&gt; &lt;h3&gt;  &lt;a href="https://fatboa.co/#&amp;#21069;&amp;#25552;" title="&amp;#21069;&amp;#25552;"&gt;&lt;/a&gt;前提&lt;/h3&gt; &lt;p&gt;我们知道一个电商项目里时刻都有海量的消息通知，比如顾客注册通知、签到通知、下单通知等等，而我们公司的电商项目更加复杂，包含了客户端、门店端以及供应商端三端，各种各样的消息通知游走在各个服务模块间。如果每个模块都要实现一套消息通知的功能，那无疑是多余的。所以我把各模块的消息功能提取出来独立成一个服务模块，就像一个快递员，把各模块的消息准确投递至各端。  &lt;br /&gt;我采用了自己熟悉的rabbitmq来实现消息功能，  &lt;br /&gt;当模块开发完交差时，组长冷不丁来了句：消息去重以及防丢失机制实现了没？w(ﾟДﾟ)w好吧，赶紧去实现。&lt;/p&gt; &lt;h3&gt;  &lt;a href="https://fatboa.co/#&amp;#28040;&amp;#24687;&amp;#21435;&amp;#37325;" title="&amp;#28040;&amp;#24687;&amp;#21435;&amp;#37325;"&gt;&lt;/a&gt;消息去重&lt;/h3&gt; &lt;p&gt;  &lt;img alt="@&amp;#28040;&amp;#24687;&amp;#22823;&amp;#33268;&amp;#27969;&amp;#31243;" src="https://fatboa.gz.bcebos.com/img/posts/rabbitmq&amp;#28040;&amp;#24687;&amp;#21435;&amp;#37325;&amp;#21450;&amp;#38450;&amp;#20002;&amp;#22833;&amp;#35299;&amp;#20915;&amp;#26041;&amp;#26696;/1553498886542.png?authorization=bce-auth-v1/b6f23434344c421e8a830ea644d98122/2019-03-26T03:51:19Z/-1/host/3d9448bad08563ec4cdcaa7a17f4d2d0b17e954d1b748645069c61bb445b0942"&gt;&lt;/img&gt;  &lt;br /&gt;依我的经验来看，在消费端去重比较好。因为即使生产端保证投递到rabbitmq上的消息是不重复的，但rabbitmq服务器有可能由于系统或网络原因导致消息重复推送到消费端，所以生产端去重是不可靠的，应当在消费端去重。&lt;/p&gt; &lt;p&gt;怎么解决呢？我的方案是在生产端投递消息的同时，传入correlationId关联id，在消费端接收消息后，从message的messageProperties中拿到correlationId，再根据correlationId从db中查询是否有相关记录。如果有，则说明这条消息已被我们消费过，直接ack，不进行业务处理；没有，那就把消息内容和correlationId存入表中，然后ack。&lt;/p&gt; &lt;blockquote&gt;  &lt;p&gt;这里说明一下，我把消息的接收和业务处理分开来了。消息监听器只负责监听队列消息，并将其存至db中。在另外的任务线程里，从db中取消息记录进去业务处理，如果业务处理中出现异常，结合elasticsearch实现异常报警（这部分还没做，目前还只是记录下错误信息及消息内容）。&lt;/p&gt;&lt;/blockquote&gt; &lt;blockquote&gt;  &lt;p&gt;why?为啥分开处理，其实一开始的设计中消息接收和处理是写在一起的，消息处理成功回复ack，处理异常回复nack。但会有一个严重的问题，但测试环境中，我们发现总有那么几条消息卡在队列里，就因为处理异常回复nack，消息一直在重入队，严重消耗rabbitmq服务器的性能！所以说，大部分异常的消息，都不能指望把消息重推到别的消费端就能处理成功了，所以消息接收和处理分开来是比较好的。&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;方案是有了，但具体代码怎么实现呢？  &lt;br /&gt;生产端关键代码：  &lt;br /&gt;  &lt;table&gt;   &lt;tr&gt;    &lt;td&gt;     &lt;pre&gt;1      &lt;br /&gt;2      &lt;br /&gt;3      &lt;br /&gt;4      &lt;br /&gt;5      &lt;br /&gt;6      &lt;br /&gt;7      &lt;br /&gt;8      &lt;br /&gt;9      &lt;br /&gt;10      &lt;br /&gt;11      &lt;br /&gt;12      &lt;br /&gt;13      &lt;br /&gt;14      &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;    &lt;td&gt;     &lt;pre&gt;public void send(String routingKey, String msg) {      &lt;br /&gt;      RabbitTemplate rabbitTemplate = applicationContext.getBean(&amp;quot;rabbitTemplate&amp;quot;, RabbitTemplate.class);      &lt;br /&gt;      rabbitTemplate.setReturnCallback(this);      &lt;br /&gt;      log.info(&amp;quot;消息发送内容 : &amp;quot; + msg);      &lt;br /&gt;      CorrelationData correlationId = new CorrelationData(UUID.randomUUID().toString());      &lt;br /&gt;      rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -&amp;gt; {      &lt;br /&gt;          if (!ack) {      &lt;br /&gt;              throw new RuntimeException(&amp;quot;send error &amp;quot; + cause);      &lt;br /&gt;          } else {      &lt;br /&gt;              log.info(&amp;quot;send() 消息发送成功 &amp;quot;);      &lt;br /&gt;          }      &lt;br /&gt;      });      &lt;br /&gt;      rabbitTemplate.convertAndSend(&amp;quot;amq.topic&amp;quot;, routingKey, msg, correlationId);      &lt;br /&gt;  }      &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt; &lt;p&gt;我们点开  &lt;code&gt;rabbitTemplate.convertAndSend&lt;/code&gt;方法  &lt;br /&gt;  &lt;table&gt;   &lt;tr&gt;    &lt;td&gt;     &lt;pre&gt;1      &lt;br /&gt;2      &lt;br /&gt;3      &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;    &lt;td&gt;     &lt;pre&gt;public void convertAndSend(String exchange, String routingKey, Object object, CorrelationData correlationData) throws AmqpException {      &lt;br /&gt;      this.send(exchange, routingKey, this.convertMessageIfNecessary(object), correlationData);      &lt;br /&gt;  }      &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt; &lt;p&gt;看到没，convertAndSend方法是以  &lt;code&gt;Object&lt;/code&gt;来接收消息内容，它内部调用的send方法最终还是把Object类转成  &lt;code&gt;Message&lt;/code&gt;类  &lt;br /&gt;  &lt;img alt="@Message.java" src="https://fatboa.gz.bcebos.com/img/posts/rabbitmq&amp;#28040;&amp;#24687;&amp;#21435;&amp;#37325;&amp;#21450;&amp;#38450;&amp;#20002;&amp;#22833;&amp;#35299;&amp;#20915;&amp;#26041;&amp;#26696;/1553502343578.png?authorization=bce-auth-v1/b6f23434344c421e8a830ea644d98122/2019-03-26T03:51:55Z/-1/host/d1ed0e35c9c9fb24cc93e02874fe28debab979be5d1b8d722333ee5d6572202b"&gt;&lt;/img&gt;  &lt;br /&gt;从上图可以看的出，Message包含了  &lt;code&gt;ENCODING&lt;/code&gt;（编码方式）、  &lt;code&gt;SERIALIZER_MESSAGE_CONVERTER&lt;/code&gt;（序列化消息转换器）、  &lt;code&gt;messageProperties&lt;/code&gt;（消息属性）、  &lt;code&gt;body&lt;/code&gt;（消息内容），队列里消息存放着这些东东。  &lt;br /&gt;我们再看看  &lt;strong&gt;MessageProperties&lt;/strong&gt;里放着什么  &lt;br /&gt;  &lt;table&gt;   &lt;tr&gt;    &lt;td&gt;     &lt;pre&gt;1      &lt;br /&gt;2      &lt;br /&gt;3      &lt;br /&gt;4      &lt;br /&gt;5      &lt;br /&gt;6      &lt;br /&gt;7      &lt;br /&gt;8      &lt;br /&gt;9      &lt;br /&gt;10      &lt;br /&gt;11      &lt;br /&gt;12      &lt;br /&gt;13      &lt;br /&gt;14      &lt;br /&gt;15      &lt;br /&gt;16      &lt;br /&gt;17      &lt;br /&gt;18      &lt;br /&gt;19      &lt;br /&gt;20      &lt;br /&gt;21      &lt;br /&gt;22      &lt;br /&gt;23      &lt;br /&gt;24      &lt;br /&gt;25      &lt;br /&gt;26      &lt;br /&gt;27      &lt;br /&gt;28      &lt;br /&gt;29      &lt;br /&gt;30      &lt;br /&gt;31      &lt;br /&gt;32      &lt;br /&gt;33      &lt;br /&gt;34      &lt;br /&gt;35      &lt;br /&gt;36      &lt;br /&gt;37      &lt;br /&gt;38      &lt;br /&gt;39      &lt;br /&gt;40      &lt;br /&gt;41      &lt;br /&gt;42      &lt;br /&gt;43      &lt;br /&gt;44      &lt;br /&gt;45      &lt;br /&gt;46      &lt;br /&gt;47      &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;    &lt;td&gt;     &lt;pre&gt;public class MessageProperties implements Serializable {      &lt;br /&gt;    private static final long serialVersionUID = 1619000546531112290L;      &lt;br /&gt;    public static final String CONTENT_TYPE_BYTES = &amp;quot;application/octet-stream&amp;quot;;      &lt;br /&gt;    public static final String CONTENT_TYPE_TEXT_PLAIN = &amp;quot;text/plain&amp;quot;;      &lt;br /&gt;    public static final String CONTENT_TYPE_SERIALIZED_OBJECT = &amp;quot;application/x-java-serialized-object&amp;quot;;      &lt;br /&gt;    public static final String CONTENT_TYPE_JSON = &amp;quot;application/json&amp;quot;;      &lt;br /&gt;    public static final String CONTENT_TYPE_JSON_ALT = &amp;quot;text/x-json&amp;quot;;      &lt;br /&gt;    public static final String CONTENT_TYPE_XML = &amp;quot;application/xml&amp;quot;;      &lt;br /&gt;    public static final String SPRING_BATCH_FORMAT = &amp;quot;springBatchFormat&amp;quot;;      &lt;br /&gt;    public static final String BATCH_FORMAT_LENGTH_HEADER4 = &amp;quot;lengthHeader4&amp;quot;;      &lt;br /&gt;    public static final String SPRING_AUTO_DECOMPRESS = &amp;quot;springAutoDecompress&amp;quot;;      &lt;br /&gt;    public static final String X_DELAY = &amp;quot;x-delay&amp;quot;;      &lt;br /&gt;    public static final String DEFAULT_CONTENT_TYPE = &amp;quot;application/octet-stream&amp;quot;;      &lt;br /&gt;    public static final MessageDeliveryMode DEFAULT_DELIVERY_MODE;      &lt;br /&gt;    public static final Integer DEFAULT_PRIORITY;      &lt;br /&gt;    private final Map&amp;lt;String, Object&amp;gt; headers = new HashMap();      &lt;br /&gt;    private volatile Date timestamp;      &lt;br /&gt;    private volatile String messageId;      &lt;br /&gt;    private volatile String userId;      &lt;br /&gt;    private volatile String appId;      &lt;br /&gt;    private volatile String clusterId;      &lt;br /&gt;    private volatile String type;      &lt;br /&gt;    private volatile String correlationId;      &lt;br /&gt;    private volatile String replyTo;      &lt;br /&gt;    private volatile String contentType = &amp;quot;application/octet-stream&amp;quot;;      &lt;br /&gt;    private volatile String contentEncoding;      &lt;br /&gt;    private volatile long contentLength;      &lt;br /&gt;    private volatile boolean contentLengthSet;      &lt;br /&gt;    private volatile MessageDeliveryMode deliveryMode;      &lt;br /&gt;    private volatile String expiration;      &lt;br /&gt;    private volatile Integer priority;      &lt;br /&gt;    private volatile Boolean redelivered;      &lt;br /&gt;    private volatile String receivedExchange;      &lt;br /&gt;    private volatile String receivedRoutingKey;      &lt;br /&gt;    private volatile String receivedUserId;      &lt;br /&gt;    private volatile long deliveryTag;      &lt;br /&gt;    private volatile boolean deliveryTagSet;      &lt;br /&gt;    private volatile Integer messageCount;      &lt;br /&gt;    private volatile String consumerTag;      &lt;br /&gt;    private volatile String consumerQueue;      &lt;br /&gt;    private volatile Integer receivedDelay;      &lt;br /&gt;    private volatile MessageDeliveryMode receivedDeliveryMode;      &lt;br /&gt;    private volatile boolean finalRetryForMessageWithNoId;      &lt;br /&gt;    private transient volatile Type inferredArgumentType;      &lt;br /&gt;    private transient volatile Method targetMethod;      &lt;br /&gt;    private transient volatile Object targetBean;      &lt;br /&gt;}      &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt; &lt;p&gt;果然  &lt;code&gt;correlationId&lt;/code&gt;就在这里，然后看到这里我就没继续深入了，原以为rabbitTemplate.convertAndSend方法会自动将correlationId放入messageProperties中，结果表明我错了。在消费端拿到的correlationId为  &lt;code&gt;null&lt;/code&gt;。也就是说，convertAndSend方法里correlationId根本就没有被放进去的，大家感兴趣的话可以看看源码，这里就不说了。&lt;/p&gt; &lt;p&gt;问题找出来就好办了  &lt;br /&gt;  &lt;table&gt;   &lt;tr&gt;    &lt;td&gt;     &lt;pre&gt;1      &lt;br /&gt;2      &lt;br /&gt;3      &lt;br /&gt;4      &lt;br /&gt;5      &lt;br /&gt;6      &lt;br /&gt;7      &lt;br /&gt;8      &lt;br /&gt;9      &lt;br /&gt;10      &lt;br /&gt;11      &lt;br /&gt;12      &lt;br /&gt;13      &lt;br /&gt;14      &lt;br /&gt;15      &lt;br /&gt;16      &lt;br /&gt;17      &lt;br /&gt;18      &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;    &lt;td&gt;     &lt;pre&gt;public void send(String routingKey, String msg) {      &lt;br /&gt;      RabbitTemplate rabbitTemplate = applicationContext.getBean(&amp;quot;rabbitTemplate&amp;quot;, RabbitTemplate.class);      &lt;br /&gt;      rabbitTemplate.setReturnCallback(this);      &lt;br /&gt;      log.info(&amp;quot;消息发送内容 : &amp;quot; + msg);      &lt;br /&gt;      CorrelationData correlationId = new CorrelationData(UUID.randomUUID().toString());      &lt;br /&gt;      rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -&amp;gt; {      &lt;br /&gt;          if (!ack) {      &lt;br /&gt;              throw new RuntimeException(&amp;quot;send error &amp;quot; + cause);      &lt;br /&gt;          } else {      &lt;br /&gt;              log.info(&amp;quot;send() 消息发送成功 &amp;quot;);      &lt;br /&gt;          }      &lt;br /&gt;      });      &lt;br /&gt;      Message message = MessageBuilder.withBody(msg.getBytes())      &lt;br /&gt;              .setContentType(MessageProperties.CONTENT_TYPE_TEXT_PLAIN)      &lt;br /&gt;              .setCorrelationId(correlationId.toString())      &lt;br /&gt;              .build();      &lt;br /&gt;      rabbitTemplate.convertAndSend(&amp;quot;amq.topic&amp;quot;, routingKey, message, correlationId);      &lt;br /&gt;  }      &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt; &lt;p&gt;直接构建Message类，手动传入correlationId总行了吧。在消费端从Message里拿到correlationId，再从db查询就行了。好了，到这里去重机制就实现了&lt;/p&gt; &lt;h3&gt;  &lt;a href="https://fatboa.co/#&amp;#28040;&amp;#24687;&amp;#38450;&amp;#20002;&amp;#22833;" title="&amp;#28040;&amp;#24687;&amp;#38450;&amp;#20002;&amp;#22833;"&gt;&lt;/a&gt;消息防丢失&lt;/h3&gt; &lt;p&gt;rabbitmq是支持队列、消息的持久化的。即便rabbitmq突然挂了，那些尚在队列未能推送的消息在rabbitmq重启后也是能够继续推送的，所以丢失问题一般不出现在rabbitmq上。&lt;/p&gt; &lt;p&gt;rabbitmq将消息从队列推到消费端后，需要有一个回应告诉它队列里的这条消息的去留。主要有两种方式：&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;auto: 自动回应，消息在发送给消费端后立即确认&lt;/li&gt;  &lt;li&gt;manual 手动回应，消息消费正常后由消费端返回ack;或消费异常返回nack,将消息重入队；或返回reject,丢弃该条消息&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;  &lt;strong&gt;   &lt;em&gt;springboot的yaml配置&lt;/em&gt;&lt;/strong&gt;  &lt;br /&gt;  &lt;table&gt;   &lt;tr&gt;    &lt;td&gt;     &lt;pre&gt;1      &lt;br /&gt;2      &lt;br /&gt;3      &lt;br /&gt;4      &lt;br /&gt;5      &lt;br /&gt;6      &lt;br /&gt;7      &lt;br /&gt;8      &lt;br /&gt;9      &lt;br /&gt;10      &lt;br /&gt;11      &lt;br /&gt;12      &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;    &lt;td&gt;     &lt;pre&gt;rabbitmq:      &lt;br /&gt;   host: 127.0.0.1      &lt;br /&gt;   port: 5672      &lt;br /&gt;   username: admin      &lt;br /&gt;   password: admin      &lt;br /&gt;   publisher-confirms: true #开启confirmcallback      &lt;br /&gt;   publisher-returns: true #开启returncallback      &lt;br /&gt;   listener:      &lt;br /&gt;     simple:      &lt;br /&gt;       acknowledge-mode: manual      &lt;br /&gt;     direct:      &lt;br /&gt;       acknowledge-mode: MANUAL      &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt; &lt;p&gt;另外，如果消息在消费的时候，消费端与rabbitmq的连接中断了，那这条消息会被重新放回队列进行推送，这个时候我们的去重机制就起作用了；如果消费的时候，消费端死机了，长时间不回应rabbitmq，这时候我们可以将该消息转至死信队列，防止原队列阻塞。死信队列，这里也不做介绍，有兴趣百度呗。  &lt;br /&gt;所以消费端出现消息丢失的可能性也不大，问题就可能出在生产端。看看下面这张图  &lt;br /&gt;  &lt;img alt="@&amp;#26469;&amp;#28304;&amp;#20110;&amp;#32593;&amp;#32476;" src="https://fatboa.gz.bcebos.com/img/posts/rabbitmq&amp;#28040;&amp;#24687;&amp;#21435;&amp;#37325;&amp;#21450;&amp;#38450;&amp;#20002;&amp;#22833;&amp;#35299;&amp;#20915;&amp;#26041;&amp;#26696;/1553504804445.png?authorization=bce-auth-v1/b6f23434344c421e8a830ea644d98122/2019-03-26T03:53:09Z/-1/host/09aeca4e5e399a3fefcf467a3bb5eed2f3154ca506790cf53590402c8ae71575"&gt;&lt;/img&gt;  &lt;br /&gt;左边P代表生产端，中间是rabbitmq，右边是消费端，绿色的X是交换机，红色的是队列，用过rabbitmq的小伙伴肯定一目了然了。&lt;/p&gt; &lt;p&gt;rabbitmq 整个消息投递的路径为：  &lt;br /&gt;  &lt;code&gt;producer&lt;/code&gt;-&amp;gt;  &lt;code&gt;rabbitmq broker cluster&lt;/code&gt;-&amp;gt;  &lt;code&gt;exchange&lt;/code&gt;-&amp;gt;  &lt;code&gt;queue&lt;/code&gt;-&amp;gt;  &lt;code&gt;consumer&lt;/code&gt;&lt;/p&gt; &lt;p&gt;生产端投递消息到rabbitmq里，rabbitmq将消息发到交换机中，交换机再根据路由键将消息最终送到队列中，队列取出消息推送到消费端。只有最终抵达队列的消息才是可靠的，不会丢失。所以我们要实现的就是保证生产端的消息务必推送到rabbitmq的队列中。&lt;/p&gt; &lt;p&gt;那么生产端是怎么知道自己的消费准确投递到了队列中呢？rabbitmq返回了两个回调给生产端。&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;message 从 producer 到 rabbitmq broker cluster 则会返回一个    &lt;code&gt;confirmCallback&lt;/code&gt; &lt;/li&gt;  &lt;li&gt;message 从 exchange-&amp;gt;queue 投递失败则会返回一个    &lt;code&gt;returnCallback&lt;/code&gt; 。我们将利用这两个 callback 控制消息的最终一致性和部分纠错能力。&lt;/li&gt;&lt;/ul&gt; &lt;h4&gt;  &lt;a href="https://fatboa.co/#&amp;#35299;&amp;#20915;&amp;#26041;&amp;#26696;" title="&amp;#35299;&amp;#20915;&amp;#26041;&amp;#26696;"&gt;&lt;/a&gt;解决方案&lt;/h4&gt; &lt;p&gt;生产端在投递消息前，先将消息内容、投递状态、重试次数记录在db中，然后在两个回调中修改记录状态。另外再开一个任务线程去取db中记录的失败消息，进行重新投递。&lt;/p&gt; &lt;h4&gt;  &lt;a href="https://fatboa.co/#&amp;#20195;&amp;#30721;&amp;#23454;&amp;#29616;" title="&amp;#20195;&amp;#30721;&amp;#23454;&amp;#29616;"&gt;&lt;/a&gt;代码实现&lt;/h4&gt; &lt;p&gt;  &lt;strong&gt;   &lt;em&gt;失败消息记录实体类：&lt;/em&gt;&lt;/strong&gt;  &lt;br /&gt;  &lt;table&gt;   &lt;tr&gt;    &lt;td&gt;     &lt;pre&gt;1      &lt;br /&gt;2      &lt;br /&gt;3      &lt;br /&gt;4      &lt;br /&gt;5      &lt;br /&gt;6      &lt;br /&gt;7      &lt;br /&gt;8      &lt;br /&gt;9      &lt;br /&gt;10      &lt;br /&gt;11      &lt;br /&gt;12      &lt;br /&gt;13      &lt;br /&gt;14      &lt;br /&gt;15      &lt;br /&gt;16      &lt;br /&gt;17      &lt;br /&gt;18      &lt;br /&gt;19      &lt;br /&gt;20      &lt;br /&gt;21      &lt;br /&gt;22      &lt;br /&gt;23      &lt;br /&gt;24      &lt;br /&gt;25      &lt;br /&gt;26      &lt;br /&gt;27      &lt;br /&gt;28      &lt;br /&gt;29      &lt;br /&gt;30      &lt;br /&gt;31      &lt;br /&gt;32      &lt;br /&gt;33      &lt;br /&gt;34      &lt;br /&gt;35      &lt;br /&gt;36      &lt;br /&gt;37      &lt;br /&gt;38      &lt;br /&gt;39      &lt;br /&gt;40      &lt;br /&gt;41      &lt;br /&gt;42      &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;    &lt;td&gt;     &lt;pre&gt;/**      &lt;br /&gt; * @time: 2019/2/18 9:14      &lt;br /&gt; * @author: hl      &lt;br /&gt; * @descripe: 失败消息记录      &lt;br /&gt; * @version: 1.0      &lt;br /&gt; */      &lt;br /&gt;Entity      &lt;br /&gt;@Table(name = &amp;quot;t_failure_mq_record&amp;quot;)      &lt;br /&gt;@Data      &lt;br /&gt;@NoArgsConstructor      &lt;br /&gt;@EntityListeners(AuditingEntityListener.class)      &lt;br /&gt;public class FailureMqRecord extends Uuid {      &lt;br /&gt;    /**      &lt;br /&gt;     * 失败消息内容      &lt;br /&gt;     */      &lt;br /&gt;    private String message;      &lt;br /&gt;    /**      &lt;br /&gt;     * 重试次数      &lt;br /&gt;     */      &lt;br /&gt;    @Column(name = &amp;quot;retry_time&amp;quot;)      &lt;br /&gt;    private Integer retryTime;      &lt;br /&gt;      &lt;br /&gt;    /**      &lt;br /&gt;     * 消息状态 1:投递成功 2：投递失败      &lt;br /&gt;     */      &lt;br /&gt;    private Integer status;      &lt;br /&gt;      &lt;br /&gt;    /**      &lt;br /&gt;     * 关联id      &lt;br /&gt;     */      &lt;br /&gt;    private String correlationId;      &lt;br /&gt;    /**      &lt;br /&gt;     * 创建时间      &lt;br /&gt;     */      &lt;br /&gt;    @CreatedDate      &lt;br /&gt;    @Column(name = &amp;quot;create_time&amp;quot;, updatable = false)      &lt;br /&gt;    private Date createTime;      &lt;br /&gt;      &lt;br /&gt;    public FailureMqRecord(String message) {      &lt;br /&gt;        this.message = message;      &lt;br /&gt;    }      &lt;br /&gt;}      &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt; &lt;p&gt;  &lt;strong&gt;   &lt;em&gt;rabbitmq发送器：&lt;/em&gt;&lt;/strong&gt;  &lt;br /&gt;  &lt;table&gt;   &lt;tr&gt;    &lt;td&gt;     &lt;pre&gt;1      &lt;br /&gt;2      &lt;br /&gt;3      &lt;br /&gt;4      &lt;br /&gt;5      &lt;br /&gt;6      &lt;br /&gt;7      &lt;br /&gt;8      &lt;br /&gt;9      &lt;br /&gt;10      &lt;br /&gt;11      &lt;br /&gt;12      &lt;br /&gt;13      &lt;br /&gt;14      &lt;br /&gt;15      &lt;br /&gt;16      &lt;br /&gt;17      &lt;br /&gt;18      &lt;br /&gt;19      &lt;br /&gt;20      &lt;br /&gt;21      &lt;br /&gt;22      &lt;br /&gt;23      &lt;br /&gt;24      &lt;br /&gt;25      &lt;br /&gt;26      &lt;br /&gt;27      &lt;br /&gt;28      &lt;br /&gt;29      &lt;br /&gt;30      &lt;br /&gt;31      &lt;br /&gt;32      &lt;br /&gt;33      &lt;br /&gt;34      &lt;br /&gt;35      &lt;br /&gt;36      &lt;br /&gt;37      &lt;br /&gt;38      &lt;br /&gt;39      &lt;br /&gt;40      &lt;br /&gt;41      &lt;br /&gt;42      &lt;br /&gt;43      &lt;br /&gt;44      &lt;br /&gt;45      &lt;br /&gt;46      &lt;br /&gt;47      &lt;br /&gt;48      &lt;br /&gt;49      &lt;br /&gt;50      &lt;br /&gt;51      &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;    &lt;td&gt;     &lt;pre&gt;/**      &lt;br /&gt; * @time: 2019/2/13 9:47      &lt;br /&gt; * @author: hl      &lt;br /&gt; * @descripe:      &lt;br /&gt; * @version: 1.0      &lt;br /&gt; */      &lt;br /&gt;@Component      &lt;br /&gt;@Slf4j      &lt;br /&gt;public class RabbitMqSender implements RabbitTemplate.ReturnCallback {      &lt;br /&gt;    @Autowired      &lt;br /&gt;    private ApplicationContext applicationContext;      &lt;br /&gt;    @Autowired      &lt;br /&gt;    private FailureMqRecordRepository failureMqRecordRepository;      &lt;br /&gt;      &lt;br /&gt;    public void send(String routingKey, FailureMqRecord failureMqRecord) {      &lt;br /&gt;        RabbitTemplate rabbitTemplate = applicationContext.getBean(&amp;quot;rabbitTemplate&amp;quot;, RabbitTemplate.class);      &lt;br /&gt;        //设置当前实例为rabbitmqtemplate的returncallback      &lt;br /&gt;        rabbitTemplate.setReturnCallback(this);      &lt;br /&gt;        rabbitTemplate.setConfirmCallback(((correlationData1, ack, cause) -&amp;gt; {      &lt;br /&gt;            if (!ack) { //投递至broker失败      &lt;br /&gt;                failureMqRecord.setStatus(2);//设为投递失败      &lt;br /&gt;                failureMqRecordRepository.save(failureMqRecord);      &lt;br /&gt;            }      &lt;br /&gt;        }));      &lt;br /&gt;        Message message = MessageBuilder.withBody(failureMqRecord.getMessage().getBytes())      &lt;br /&gt;                .setContentType(MessageProperties.CONTENT_TYPE_TEXT_PLAIN)      &lt;br /&gt;                .setCorrelationId(failureMqRecord.getCorrelationId())      &lt;br /&gt;                .build();      &lt;br /&gt;        rabbitTemplate.convertAndSend(&amp;quot;amq.topic&amp;quot;, routingKey, message, new CorrelationData(failureMqRecord.getCorrelationId()));      &lt;br /&gt;        failureMqRecord.setStatus(1);//设为投递成功      &lt;br /&gt;        failureMqRecord.setRetryTime(failureMqRecord.getRetryTime() + 1);//重试次数+1      &lt;br /&gt;        failureMqRecordRepository.save(failureMqRecord);      &lt;br /&gt;    }      &lt;br /&gt;      &lt;br /&gt;    /**      &lt;br /&gt;     * 消息由exchang未能正确投递到queue时触发回调      &lt;br /&gt;     *      &lt;br /&gt;     * @param message      &lt;br /&gt;     * @param replyCode      &lt;br /&gt;     * @param replyText      &lt;br /&gt;     * @param exchange      &lt;br /&gt;     * @param routingKey      &lt;br /&gt;     */      &lt;br /&gt;    @Override      &lt;br /&gt;    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) throws BusinessException {      &lt;br /&gt;        FailureMqRecord mq = failureMqRecordRepository.findByCorrelationId(message.getMessageProperties().getCorrelationId());      &lt;br /&gt;        mq.setStatus(2);      &lt;br /&gt;        failureMqRecordRepository.save(mq);      &lt;br /&gt;        log.error(&amp;quot;审批消息：{} 投递至路由：{}失败&amp;quot;, message.getBody(), routingKey);      &lt;br /&gt;    }      &lt;br /&gt;}      &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt; &lt;p&gt;  &lt;strong&gt;   &lt;em&gt;任务线程，实现消息重试机制：&lt;/em&gt;&lt;/strong&gt;  &lt;br /&gt;  &lt;table&gt;   &lt;tr&gt;    &lt;td&gt;     &lt;pre&gt;1      &lt;br /&gt;2      &lt;br /&gt;3      &lt;br /&gt;4      &lt;br /&gt;5      &lt;br /&gt;6      &lt;br /&gt;7      &lt;br /&gt;8      &lt;br /&gt;9      &lt;br /&gt;10      &lt;br /&gt;11      &lt;br /&gt;12      &lt;br /&gt;13      &lt;br /&gt;14      &lt;br /&gt;15      &lt;br /&gt;16      &lt;br /&gt;17      &lt;br /&gt;18      &lt;br /&gt;19      &lt;br /&gt;20      &lt;br /&gt;21      &lt;br /&gt;22      &lt;br /&gt;23      &lt;br /&gt;24      &lt;br /&gt;25      &lt;br /&gt;26      &lt;br /&gt;27      &lt;br /&gt;28      &lt;br /&gt;29      &lt;br /&gt;30      &lt;br /&gt;31      &lt;br /&gt;32      &lt;br /&gt;33      &lt;br /&gt;34      &lt;br /&gt;35      &lt;br /&gt;36      &lt;br /&gt;37      &lt;br /&gt;38      &lt;br /&gt;39      &lt;br /&gt;40      &lt;br /&gt;41      &lt;br /&gt;42      &lt;br /&gt;43      &lt;br /&gt;44      &lt;br /&gt;45      &lt;br /&gt;46      &lt;br /&gt;47      &lt;br /&gt;48      &lt;br /&gt;49      &lt;br /&gt;50      &lt;br /&gt;51      &lt;br /&gt;52      &lt;br /&gt;53      &lt;br /&gt;54      &lt;br /&gt;55      &lt;br /&gt;56      &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;    &lt;td&gt;     &lt;pre&gt;/**      &lt;br /&gt; * @time: 2019/2/18 10:10      &lt;br /&gt; * @author: huanglong      &lt;br /&gt; * @descripe: 消息重发定时器      &lt;br /&gt; * @version: 1.0      &lt;br /&gt; */      &lt;br /&gt;@Component      &lt;br /&gt;@Slf4j      &lt;br /&gt;public class MqScheduler {      &lt;br /&gt;    @Autowired      &lt;br /&gt;    private RabbitMqSender rabbitMqSender;      &lt;br /&gt;    @Autowired      &lt;br /&gt;    private ApprovalMqRepository failureMqRecordRepository;      &lt;br /&gt;    @Autowired      &lt;br /&gt;    private RedisDistributedLock redisDistributedLock;      &lt;br /&gt;      &lt;br /&gt;    /**      &lt;br /&gt;     * 每3分钟执行一次      &lt;br /&gt;     * 将投递失败消息重新投递到rabbitmq      &lt;br /&gt;     */      &lt;br /&gt;    @Scheduled(cron = &amp;quot;* */3 * * * ?&amp;quot;)      &lt;br /&gt;    void push() {      &lt;br /&gt;        List&amp;lt;FailureMqRecord&amp;gt; failureMqRecords = failureMqRecordRepository.findAll()      &lt;br /&gt;                .stream()      &lt;br /&gt;                .filter(failureMqRecord -&amp;gt; {      &lt;br /&gt;                    if (failureMqRecord.getRetryTime() == 3) {      &lt;br /&gt;                        log.error(&amp;quot;警告！该消息已重投3次失败，请人工处理，消息记录uuid:{}&amp;quot;, failureMqRecord.getUuid());      &lt;br /&gt;                    }      &lt;br /&gt;                    //过滤出重试次数不超过3次、状态为2的消息记录      &lt;br /&gt;                    if (failureMqRecord.getRetryTime() &amp;lt; 3 &amp;amp;&amp;amp; failureMqRecord.getStatus() == 0) {      &lt;br /&gt;                        return true;      &lt;br /&gt;                    }      &lt;br /&gt;                    return false;      &lt;br /&gt;                })      &lt;br /&gt;                .collect(Collectors.toList());      &lt;br /&gt;      &lt;br /&gt;        Iterator&amp;lt;FailureMqRecord&amp;gt; mqIterator = failureMqRecords.iterator();      &lt;br /&gt;        while (mqIterator.hasNext()) {      &lt;br /&gt;            FailureMqRecord failureMqRecord = mqIterator.next();      &lt;br /&gt;            //获取,过期时间5秒，不重复获取      &lt;br /&gt;            if (redisDistributedLock.lock(failureMqRecord.getUuid(), 5000L, 0, 1000L)) {      &lt;br /&gt;                // 因为有可能上一个线程刚释放该记录的锁，就被当前先线程获取到该记录的锁，导致记录已被      &lt;br /&gt;                FailureMqRecord failurelatest = failureMqRecordRepository.findById(failureMqRecord.getUuid()).orElse(null);      &lt;br /&gt;                ApprovalPushMessage pushMessage = JSON.parseObject(failurelatest.getMessage(), ApprovalPushMessage.class);      &lt;br /&gt;                //当前时间距离该记录最近一次修改时间的间隔，防止上个线程重试过后，当前线程又重试一次      &lt;br /&gt;                long lastUpdatePeriod = System.currentTimeMillis() - failurelatest.getUpdateTime().getTime(); //距离上次更新间隔      &lt;br /&gt;                //重判断记录是否符合条件,重试次数小于3、状态为投递失败、距离上次重试不能少于2分钟      &lt;br /&gt;                if (failurelatest.getRetryTime() &amp;lt; 3 &amp;amp;&amp;amp; failurelatest.getStatus() == 2 &amp;amp;&amp;amp; lastUpdatePeriod &amp;gt; 2 * 60 * 1000) {      &lt;br /&gt;                    rabbitMqSender.send(&amp;quot;approval.create&amp;quot;, failureMqRecord);      &lt;br /&gt;                }      &lt;br /&gt;                //释放      &lt;br /&gt;                redisDistributedLock.releaseLock(failureMqRecord.getUuid());      &lt;br /&gt;            }      &lt;br /&gt;        }      &lt;br /&gt;    }      &lt;br /&gt;}      &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt; &lt;p&gt;聪明的小伙伴看到这里，会发现任务线程里还用到了分布式。为啥还要加分布式锁，因为是分布式架构啊，会有多个相同定时器从db里取记录处理，如果不加分布式锁，那真的要乱套了。因为redis用的多，就用redis来实现分布式锁了，zookeeper啥的，有空再研究了。redis分布式锁的代码实现，网上有很多资源，我这里就不贴了，嘿嘿&lt;/p&gt; &lt;p&gt;好了，到这里rabbitmq的去重以及防丢失方案已经实现了，如果你有更好的解决方案或者指出我方案的不足，欢迎留言讨论&lt;/p&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>后端笔记 rabbitmq</category>
      <guid isPermaLink="true">https://itindex.net/detail/59929-rabbitmq-%E6%B6%88%E6%81%AF</guid>
      <pubDate>Fri, 22 Mar 2019 11:38:54 CST</pubDate>
    </item>
    <item>
      <title>读物联网开放平台01(6.17)</title>
      <link>https://itindex.net/detail/59707-%E7%89%A9%E8%81%94%E7%BD%91-%E5%BC%80%E6%94%BE%E5%B9%B3%E5%8F%B0</link>
      <description>&lt;div&gt;  &lt;a href="http://album.sina.com.cn/pic/001l8XD7zy7uILhhAzHdd" target="_blank"&gt;   &lt;img src="http://s14.sinaimg.cn/mw690/001l8XD7zy7uILhhAzHdd&amp;690"&gt;&lt;/img&gt;&lt;/a&gt;  &lt;br /&gt;
  &lt;br /&gt;&lt;/div&gt;
全书名为《物联网开放平台-平台架构、关键技术和典型应用》，准备2到3篇文章将关键内容整理下。今天主要整理下本身的第1,2章，涉及到物联网概述，物联网体系基础技术方面的内容。
 &lt;div&gt;  &lt;br /&gt;&lt;/div&gt;
 &lt;div&gt;
  &lt;div&gt;
   &lt;strong&gt;物联网：&lt;/strong&gt;各种物通过各种传感类设备接入到互联网，建立物和物，物和人之间的连接和通信，以实现智能化识别，定位，监控和管理的一种网络。因此可以到设备和传感层，网络层是最基础的两层，也是我们需要在传统软件类架构上增加的层次。&lt;/div&gt;
  &lt;div&gt;   &lt;br /&gt;&lt;/div&gt;
  &lt;div&gt;物联网的发展加速的几个关键点&lt;/div&gt;
  &lt;div&gt;   &lt;br /&gt;&lt;/div&gt;
  &lt;div&gt;   &lt;strong&gt;1. 网络发展&lt;/strong&gt;：互联网带宽，移动互联网，5G，NB-IoT，通信网等&lt;/div&gt;
  &lt;div&gt;   &lt;strong&gt;2. 云基础平台&lt;/strong&gt;：信息采集要到云端处理和应用，涉及到云计算基础平台，大数据平台等&lt;/div&gt;
  &lt;div&gt;   &lt;strong&gt;3. 人工智能&lt;/strong&gt;：历史数据积累，算法演进，万物互联是基础，万物智能化才是目标&lt;/div&gt;
  &lt;div&gt;   &lt;br /&gt;&lt;/div&gt;
  &lt;div&gt;
通过网络通信后，物理装置映射到信息世界中的信息，一个物理装置可以通过一个或多个虚拟事物(映射)在信息世界中表达，但是虚拟事物的存在也可以和物理装置不相关。装置一般来说负责收集信息，并将其提供给信息网络做进一步处理。&lt;/div&gt;
  &lt;div&gt;   &lt;br /&gt;&lt;/div&gt;
  &lt;div&gt;
   &lt;strong&gt;物联网的核心是物与物，物与人之间的信息交互，即我们说的万物互联&lt;/strong&gt;，通过万物互联形成各种新的聚合服务能力。   &lt;strong&gt;物联网的基本特征可以概括为全面感知，可靠传送和智能处理&lt;/strong&gt;。全面感知即我们常说的RFID，条码，传感器，监控等各类传感类设备的使用；而可靠传送则需要的是通信网络和信息网络的融合，即我们说的ICT；智能处理涉及到信息网，包括了云计算，大数据，人工智能等。&lt;/div&gt;
  &lt;div&gt;   &lt;br /&gt;&lt;/div&gt;
  &lt;div&gt;
可以看到，不管是原来谈智慧城市，还是现在谈智慧家庭，其架构和体系都满足物联网的核心特征。需要解决的是硬件，软件，人的连接问题；同时在解决连接问题后需要解决服务聚合，能力开放和最终的智能化处理和应用问题。&lt;/div&gt;
  &lt;div&gt;   &lt;br /&gt;&lt;/div&gt;
  &lt;div&gt;
   &lt;strong&gt;物联网和互联网区别，将信息和人的交互延伸到物理世界。信息和人的交互变化为：信息和人，信息和物，物和人，包括物和物多者之间的交互，形成万物互联。&lt;/strong&gt;&lt;/div&gt;
  &lt;div&gt;   &lt;br /&gt;&lt;/div&gt;
  &lt;div&gt;
   &lt;strong&gt;传感器网络：&lt;/strong&gt;包含互联的传感器节点的网络，传感器节点是由传感器和可选的能检测处理数据及联网的执行元件组成的设备，传感器感知物理条件或化学成分，并且传递与被观察的特性成比例的电信号的电子设备。传感器节点具有数据采集，处理，无线通信和自组织的能力。泛在网络：无处不在的网络，能够实现随时随地的任何人和物之间的通信和信息交互，信息的采集，处理，存储和决策等。是多网络多技术的一个总称，涉及到多个异构网络的连接。泛在网的概念和范围最大。&lt;/div&gt;
  &lt;div&gt;   &lt;br /&gt;&lt;/div&gt;
  &lt;div&gt;
物联网，大范畴智慧城市，智能电网，小范畴类似智慧家庭，智慧家庭，车联网等。进入制造企业，现在的工业4.0，工业互联网，智能制造。底层仍然涉及到物联网技术应用。&lt;/div&gt;
  &lt;div&gt;   &lt;br /&gt;&lt;/div&gt;
  &lt;div&gt;   &lt;strong&gt;物联网的体系架构&lt;/strong&gt;&lt;/div&gt;
  &lt;div&gt;   &lt;br /&gt;&lt;/div&gt;
  &lt;div&gt;
目前被广泛认可的物联网体系架构分为三层，即   &lt;strong&gt;感知层，网络层和应用层&lt;/strong&gt;。在这种划分方法下，云计算平台，数据中心等往往会被划到网络层或应用层里面。因此更好的一种方法是分为四层，   &lt;strong&gt;从底向上分别为感知控制层，网络层，平台服务层，应用服务层&lt;/strong&gt;。对于平台服务层则已经到了软件层面的底层平台，包括云计算平台，大数据平台，集成平台，技术服务平台等。这个也是我们原来在智慧城市总体架构体系规划里面经常会使用的一种架构分层方法。&lt;/div&gt;
  &lt;div&gt;   &lt;br /&gt;&lt;/div&gt;
  &lt;div&gt;   &lt;strong&gt;感知层&lt;/strong&gt;&lt;/div&gt;
  &lt;div&gt;   &lt;br /&gt;&lt;/div&gt;
  &lt;div&gt;
   &lt;strong&gt;RFID&lt;/strong&gt;是一种利用射频信号通过空间耦合(交变磁场或电磁场)实现的无接触式信息传递，并通过所有传递的信息达到自动识别的技术。阅读区和电子标签之间的能量感应一般有两种方式，一种是低功率下的电感耦合，一种是高功率下的电磁反向散射耦合。读写器发出查询信号，激活标签，标签按要求反射信号，读写器收到反射信息好进行数据处理。&lt;/div&gt;
  &lt;div&gt;   &lt;br /&gt;&lt;/div&gt;
  &lt;div&gt;
   &lt;strong&gt;WSN无线传感网络&lt;/strong&gt;是一种新兴网络，是由部署在监测区域内大量的廉价微型传感器节点组成，通过无线通信方式形成一个多跳自组织的网络系统。&lt;/div&gt;
  &lt;div&gt;   &lt;br /&gt;&lt;/div&gt;
  &lt;div&gt;   &lt;strong&gt;ZigBee技术&lt;/strong&gt;是一种新兴的短距离无线通信技术，基于IEEE
802.15.4标准，强调简单易用，低距离，低速率，低功耗的市场定位，广泛应用于工业控制，智慧家庭，智慧医疗等。ZigBee协议栈分为底层硬件模块，中间协议层和高端应用层三大部分组成。其中底层硬件模块是ZigBee的核心模块，所有嵌入ZigBee技术的设备都必须考虑底层硬件模块，它主要由射频RF，ZigBee无线收发器和底层控制模块组成。&lt;/div&gt;
  &lt;div&gt;   &lt;br /&gt;&lt;/div&gt;
  &lt;div&gt;
   &lt;strong&gt;MEMS技术和传感器：&lt;/strong&gt;对于力热光电，化学气体湿度，生物等信息的采集，当前应用做多的则是MEMS技术和传感器。MEMS传感器是采用微机械加工技术制造的新型传感器，随着微电子，集成电路技术的发展，MEMS传感器凭借体积小，质量轻，功耗低，可靠性高，灵敏度高，易集成等特点被广泛应用。包括消费电子产品，工业制造，航空航天，化工农业等多个领域。&lt;/div&gt;
  &lt;div&gt;   &lt;br /&gt;&lt;/div&gt;
  &lt;div&gt;   &lt;strong&gt;网络层&lt;/strong&gt;&lt;/div&gt;
  &lt;div&gt;   &lt;br /&gt;&lt;/div&gt;
  &lt;div&gt;
   &lt;strong&gt;LoRa&lt;/strong&gt;是由Semtech公司提供的超长距离，低功耗物联网解决方案，其中LoRa联盟推出LoRaWAN技术标准，国内在抄表，石油生产监测等诸多领域均有应用。LoRa网络架构中包括应用终端，网关，网络服务器和业务服务器等。其中，应用终端节点完成物理层，MAC层和应用层的实现；网关完成空口物理层的处理；网络服务器服务进行MAC层处理。LoRa为半双工系统，上行和下行工作在同一个频段，当前国内单芯片支撑的带宽为2M，包括8个固定带宽为128k的信道。&lt;/div&gt;
  &lt;div&gt;   &lt;br /&gt;&lt;/div&gt;
  &lt;div&gt;
LoRa是一种适合于低功耗，低成本，广域物联网应用的非授权频段技术，并且已经完全满足商用条件。主要短板是对移动性的支持，以及存在时延问题，建议LoRa业务多选择数据量较低，功耗小，有深度覆盖要求且对移动性要求不高的应用场景。&lt;/div&gt;
  &lt;div&gt;   &lt;br /&gt;&lt;/div&gt;
  &lt;div&gt;
   &lt;strong&gt;基于蜂窝的窄带物联网(NB-IoT)&lt;/strong&gt;成为万物互联网络的一个重要分支。NB-IoT构建于蜂窝网络，只占用180kHz的频段，可直接部署于GSM网络，UMTS网络或LTE网络，以降低部署的成本和实现平滑升级。NB-IoT具备部署灵活，强大的网络覆盖能力，接入容量大建设成本低，终端低功耗等诸多特点。目前NB-IoT标准已经成熟，端到端产业链也在快速发展，从终端到系统，应用，整个行业都在积极推动产品成熟。&lt;/div&gt;
  &lt;div&gt;   &lt;br /&gt;&lt;/div&gt;
  &lt;div&gt;   &lt;strong&gt;物联网中间件技术&lt;/strong&gt;&lt;/div&gt;
  &lt;div&gt;   &lt;br /&gt;&lt;/div&gt;
  &lt;div&gt;
在物联网整体架构体系中，要实现海量的，有着异构属性的物体无缝的接入并整合到复杂的信息网络中进行相互通信，必须有一个统一的技术架构和标准的软件体系对此进行支撑。物联网中间件能够为解决上述问题提供统一的标准体系与通用的服务开发平台，同时为上层应用提供通用组件，以保证开发人员对底层网络的透明性。&lt;/div&gt;
  &lt;div&gt;   &lt;br /&gt;&lt;/div&gt;
  &lt;div&gt;
物联网中间件主要解决异构网络环境下分布式应用软件的通信，互操作和协同问题，提高应用系统的易移植性，适应性和可靠性。物联网中间件技术研究中关键要解决的问题和挑战包括了：&lt;/div&gt;
  &lt;div&gt;   &lt;br /&gt;&lt;/div&gt;
  &lt;div&gt;1. 复杂的分布式的异构网络环境，不同的硬件结构，驱动程序，操作系统，底层协议。&lt;/div&gt;
  &lt;div&gt;2. 应用和服务之间的重复调用和互操作&lt;/div&gt;
  &lt;div&gt;3. 海量异构数据的融合&lt;/div&gt;
  &lt;div&gt;   &lt;br /&gt;&lt;/div&gt;
  &lt;div&gt;
   &lt;strong&gt;物联网中间件重点在于解决各种应用领域异构设备的互操作，上下文感知，设备发现和管理，可扩展性，海量数据管理等问题。物联网中间件是硬件平台，硬件操作系统和Drvier驱动层到软件应用层之间的一个重要衔接&lt;/strong&gt;，能够屏蔽底层不同的服务细节，使开发人员关注于应用本身的功能实现。物联网中间件位于数据采集节点之上，应用程序之下的一种软件层，为上层应用屏蔽底层设备因采用不同技术而带来的差异。&lt;/div&gt;
  &lt;div&gt;   &lt;br /&gt;&lt;/div&gt;
  &lt;div&gt;对于PaaS平台，数据挖掘等内容大部分属于软件层面，在我原来文章里面也经常都谈到过，再次不再叙述。&lt;/div&gt;
&lt;/div&gt; &lt;br /&gt; &lt;img src="http://simg.sinajs.cn/blog7style/images/special/1265.gif"&gt;&lt;/img&gt; &lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>读书笔记</category>
      <guid isPermaLink="true">https://itindex.net/detail/59707-%E7%89%A9%E8%81%94%E7%BD%91-%E5%BC%80%E6%94%BE%E5%B9%B3%E5%8F%B0</guid>
      <pubDate>Mon, 17 Jun 2019 15:27:07 CST</pubDate>
    </item>
    <item>
      <title>使用Consul做服务发现的若干姿势</title>
      <link>https://itindex.net/detail/58972-consul-%E6%9C%8D%E5%8A%A1-%E5%8F%91%E7%8E%B0</link>
      <description>&lt;p&gt;从2016年起就开始接触Consul，使用的主要目的就是做服务发现，后来逐步应用于生产环境，并总结了少许使用经验。最开始使用Consul的人不多，为了方便交流创建了一个QQ群（群号在最后），这两年微服务越来越火，使用Consul的人也越来越多，目前群里已有400多人，经常有人问一些问题，比如：&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;服务注册到节点后，其他节点为什么没有同步？&lt;/li&gt;  &lt;li&gt;Client是干什么的？（Client有什么作用？）&lt;/li&gt;  &lt;li&gt;能不能直接注册到Server？（是否只有Server节点就够了？）&lt;/li&gt;  &lt;li&gt;服务信息是保存在哪里的？&lt;/li&gt;  &lt;li&gt;如果节点挂了健康检查能不能转移到别的节点？&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;有些人可能对服务注册和发现还没有概念，有些人可能使用过其它服务发现的工具，比如zookeeper，etcd，会有一些先入为主的经验。这篇文章将结合Consul的官方文档和自己的实际经验，谈一下Consul做服务发现的方式，文中尽量不依赖具体的框架和开发语言，从原理上进行说明，希望能够讲清楚上边的几个问题。&lt;/p&gt; &lt;h3&gt;  &lt;a href="http://blog.didispace.com/#&amp;#20026;&amp;#20160;&amp;#20040;&amp;#20351;&amp;#29992;&amp;#26381;&amp;#21153;&amp;#21457;&amp;#29616;" title="&amp;#20026;&amp;#20160;&amp;#20040;&amp;#20351;&amp;#29992;&amp;#26381;&amp;#21153;&amp;#21457;&amp;#29616;"&gt;&lt;/a&gt;为什么使用服务发现&lt;/h3&gt; &lt;p&gt;防止硬编码、容灾、水平扩缩容、提高运维效率等等，只要你想使用服务发现总能找到合适的理由。&lt;/p&gt; &lt;p&gt;一般的说法是因为使用微服务架构。传统的单体架构不够灵活不能很好的适应变化，从而向微服务架构进行转换，而伴随着大量服务的出现，管理运维十分不便，于是开始搞一些自动化的策略，服务发现应运而生。所以如果需要使用服务发现，你应该有一些对服务治理的痛点。&lt;/p&gt; &lt;p&gt;但是引入服务发现就可能引入一些技术栈，增加系统总体的复杂度，如果你只有很少的几个服务，比如10个以下，并且业务不怎么变化，吞吐量预计也很稳定，可能就没有必要使用服务发现。&lt;/p&gt; &lt;h3&gt;  &lt;a href="http://blog.didispace.com/#Consul&amp;#20869;&amp;#37096;&amp;#21407;&amp;#29702;" title="Consul&amp;#20869;&amp;#37096;&amp;#21407;&amp;#29702;"&gt;&lt;/a&gt;Consul内部原理&lt;/h3&gt; &lt;p&gt;下面这张图来源于Consul官网，很好的解释了Consul的工作原理，先大致看一下。&lt;/p&gt; &lt;p&gt;  &lt;img alt="" src="http://blog.didispace.com/images/pasted-124.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;p&gt;首先Consul支持多数据中心，在上图中有两个DataCenter，他们通过Internet互联，同时请注意为了提高通信效率，只有Server节点才加入跨数据中心的通信。&lt;/p&gt; &lt;p&gt;在单个数据中心中，Consul分为Client和Server两种节点（所有的节点也被称为Agent），Server节点保存数据，Client负责健康检查及转发数据请求到Server；Server节点有一个Leader和多个Follower，Leader节点会将数据同步到Follower，Server的数量推荐是3个或者5个，在Leader挂掉的时候会启动选举机制产生一个新的Leader。&lt;/p&gt; &lt;p&gt;集群内的Consul节点通过gossip协议（流言协议）维护成员关系，也就是说某个节点了解集群内现在还有哪些节点，这些节点是Client还是Server。单个数据中心的流言协议同时使用TCP和UDP通信，并且都使用8301端口。跨数据中心的流言协议也同时使用TCP和UDP通信，端口使用8302。&lt;/p&gt; &lt;p&gt;集群内数据的读写请求既可以直接发到Server，也可以通过Client使用RPC转发到Server，请求最终会到达Leader节点，在允许数据轻微陈旧的情况下，读请求也可以在普通的Server节点完成，集群内数据的读写和复制都是通过TCP的8300端口完成。&lt;/p&gt; &lt;h3&gt;  &lt;a href="http://blog.didispace.com/#Consul&amp;#26381;&amp;#21153;&amp;#21457;&amp;#29616;&amp;#21407;&amp;#29702;" title="Consul&amp;#26381;&amp;#21153;&amp;#21457;&amp;#29616;&amp;#21407;&amp;#29702;"&gt;&lt;/a&gt;Consul服务发现原理&lt;/h3&gt; &lt;p&gt;下面这张图是自己画的，基本描述了服务发现的完整流程，先大致看一下。&lt;/p&gt; &lt;p&gt;  &lt;img alt="" src="http://blog.didispace.com/images/pasted-125.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;p&gt;首先需要有一个正常的Consul集群，有Server，有Leader。这里在服务器Server1、Server2、Server3上分别部署了Consul Server，假设他们选举了Server2上的Consul Server节点为Leader。这些服务器上最好只部署Consul程序，以尽量维护Consul Server的稳定。&lt;/p&gt; &lt;p&gt;然后在服务器Server4和Server5上通过Consul Client分别注册Service A、B、C，这里每个Service分别部署在了两个服务器上，这样可以避免Service的单点问题。服务注册到Consul可以通过HTTP API（8500端口）的方式，也可以通过Consul配置文件的方式。Consul Client可以认为是无状态的，它将注册信息通过RPC转发到Consul Server，服务信息保存在Server的各个节点中，并且通过Raft实现了强一致性。&lt;/p&gt; &lt;p&gt;最后在服务器Server6中Program D需要访问Service B，这时候Program D首先访问本机Consul Client提供的HTTP API，本机Client会将请求转发到Consul Server，Consul Server查询到Service B当前的信息返回，最终Program D拿到了Service B的所有部署的IP和端口，然后就可以选择Service B的其中一个部署并向其发起请求了。如果服务发现采用的是DNS方式，则Program D中直接使用Service B的服务发现域名，域名解析请求首先到达本机DNS代理，然后转发到本机Consul Client，本机Client会将请求转发到Consul Server，Consul Server查询到Service B当前的信息返回，最终Program D拿到了Service B的某个部署的IP和端口。&lt;/p&gt; &lt;p&gt;图中描述的部署架构笔者认为是最普适最简单的方案，从某些默认配置或设计上看也是官方希望使用者采用的方案，比如8500端口默认监听127.0.0.1，当然有些同学不赞同，后边会提到其他方案。&lt;/p&gt; &lt;h3&gt;  &lt;a href="http://blog.didispace.com/#Consul&amp;#23454;&amp;#38469;&amp;#20351;&amp;#29992;" title="Consul&amp;#23454;&amp;#38469;&amp;#20351;&amp;#29992;"&gt;&lt;/a&gt;Consul实际使用&lt;/h3&gt; &lt;p&gt;为了更快的熟悉Consul的原理及其使用方式，最好还是自己实际测试下。&lt;/p&gt; &lt;p&gt;Consul安装十分简单，但是在一台机器上不方便搭建集群进行测试，使用虚拟机比较重，所以这里选择了docker。这里用了Windows 10，需要是专业版，因为Windows上的Docker依赖Hyper-V，而这个需要专业版才能支持。这里对于Docker的使用不会做过多的描述，如果遇到相关问题请搜索一下。&lt;/p&gt; &lt;h4&gt;  &lt;a href="http://blog.didispace.com/#&amp;#23433;&amp;#35013;Docker" title="&amp;#23433;&amp;#35013;Docker"&gt;&lt;/a&gt;安装Docker&lt;/h4&gt; &lt;p&gt;通过这个地址下载安装：&lt;/p&gt; &lt;p&gt;  &lt;a href="https://store.docker.com/editions/community/docker-ce-desktop-windows" rel="noopener" target="_blank"&gt;https://store.docker.com/editions/community/docker-ce-desktop-windows&lt;/a&gt;&lt;/p&gt; &lt;p&gt;安装完成后打开 Windows PowerShell，输入docker –version，如果正常输出docker版本就可以了。&lt;/p&gt; &lt;h4&gt;  &lt;a href="http://blog.didispace.com/#&amp;#21551;&amp;#21160;Consul&amp;#38598;&amp;#32676;" title="&amp;#21551;&amp;#21160;Consul&amp;#38598;&amp;#32676;"&gt;&lt;/a&gt;启动Consul集群&lt;/h4&gt; &lt;p&gt;在 Windows PowerShell中执行命令拉取最新版本的Consul镜像：&lt;/p&gt; &lt;table&gt;  &lt;tr&gt;   &lt;td&gt;    &lt;pre&gt;docker pull consul     &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;p&gt;然后就可以启动集群了，这里启动4个Consul Agent，3个Server（会选举出一个leader），1个Client。&lt;/p&gt; &lt;table&gt;  &lt;tr&gt;   &lt;td&gt;    &lt;pre&gt;#启动第1个Server节点，集群要求要有3个Server，将容器8500端口映射到主机8900端口，同时开启管理界面     &lt;br /&gt;docker run -d --name=consul1 -p 8900:8500 -e CONSUL_BIND_INTERFACE=eth0 consul agent --server=true --bootstrap-expect=3 --client=0.0.0.0 -ui     &lt;br /&gt;      &lt;br /&gt;#启动第2个Server节点，并加入集群     &lt;br /&gt;docker run -d --name=consul2 -e CONSUL_BIND_INTERFACE=eth0 consul agent --server=true --client=0.0.0.0 --join 172.17.0.2     &lt;br /&gt;      &lt;br /&gt;#启动第3个Server节点，并加入集群     &lt;br /&gt;docker run -d --name=consul3 -e CONSUL_BIND_INTERFACE=eth0 consul agent --server=true --client=0.0.0.0 --join 172.17.0.2     &lt;br /&gt;      &lt;br /&gt;#启动第4个Client节点，并加入集群     &lt;br /&gt;docker run -d --name=consul4 -e CONSUL_BIND_INTERFACE=eth0 consul agent --server=false --client=0.0.0.0 --join 172.17.0.2     &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;p&gt;第1个启动容器的IP一般是172.17.0.2，后边启动的几个容器IP会排着来：172.17.0.3、172.17.0.4、172.17.0.5。&lt;/p&gt; &lt;p&gt;这些Consul节点在Docker的容器内是互通的，他们通过桥接的模式通信。但是如果主机要访问容器内的网络，需要做端口映射。在启动第一个容器时，将Consul的8500端口映射到了主机的8900端口，这样就可以方便的通过主机的浏览器查看集群信息。&lt;/p&gt; &lt;p&gt;  &lt;img alt="" src="http://blog.didispace.com/images/pasted-126.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;p&gt;进入容器consul1：&lt;/p&gt; &lt;table&gt;  &lt;tr&gt;   &lt;td&gt;    &lt;pre&gt;docker exec -it consul1 /bin/sh     &lt;br /&gt;      &lt;br /&gt;#执行ls后可以看到consul就在根目录     &lt;br /&gt;ls     &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;p&gt;输入exit可以跳出容器。&lt;/p&gt; &lt;h4&gt;  &lt;a href="http://blog.didispace.com/#&amp;#26381;&amp;#21153;&amp;#27880;&amp;#20876;" title="&amp;#26381;&amp;#21153;&amp;#27880;&amp;#20876;"&gt;&lt;/a&gt;服务注册&lt;/h4&gt; &lt;p&gt;自己写一个web服务，用最熟悉的开发语言就好了，不过需要在容器中能够跑起来，可能需要安装运行环境，比如python、java、.net core等的sdk及web服务器，需要注意的是Consul的docker镜像基于alpine系统，具体运行环境的安装请搜索一下。&lt;/p&gt; &lt;p&gt;这里写了一个hello服务，通过配置文件的方式注册到Consul，服务的相关信息：&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;name：hello，服务名称，需要能够区分不同的业务服务，可以部署多份并使用相同的name注册。&lt;/li&gt;  &lt;li&gt;id：hello1，服务id，在每个节点上需要唯一，如果有重复会被覆盖。&lt;/li&gt;  &lt;li&gt;address：172.17.0.5，服务所在机器的地址。&lt;/li&gt;  &lt;li&gt;port：5000，服务的端口。&lt;/li&gt;  &lt;li&gt;健康检查地址：   &lt;a href="http://localhost:5000/&amp;#65292;&amp;#22914;&amp;#26524;&amp;#36820;&amp;#22238;HTTP&amp;#29366;&amp;#24577;&amp;#30721;&amp;#20026;200&amp;#23601;&amp;#20195;&amp;#34920;&amp;#26381;&amp;#21153;&amp;#20581;&amp;#24247;&amp;#65292;&amp;#27599;10&amp;#31186;Consul&amp;#35831;&amp;#27714;&amp;#19968;&amp;#27425;&amp;#65292;&amp;#35831;&amp;#27714;&amp;#36229;&amp;#26102;&amp;#26102;&amp;#38388;&amp;#20026;1&amp;#31186;&amp;#12290;" rel="noopener" target="_blank"&gt;http://localhost:5000/，如果返回HTTP状态码为200就代表服务健康，每10秒Consul请求一次，请求超时时间为1秒。&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;请将下面的内容保存成文件services.json，并上传到容器的/consul/config目录中。&lt;/p&gt; &lt;table&gt;  &lt;tr&gt;   &lt;td&gt;    &lt;pre&gt;{     &lt;br /&gt;  &amp;quot;services&amp;quot;: [     &lt;br /&gt;    {     &lt;br /&gt;      &amp;quot;id&amp;quot;: &amp;quot;hello1&amp;quot;,     &lt;br /&gt;      &amp;quot;name&amp;quot;: &amp;quot;hello&amp;quot;,     &lt;br /&gt;      &amp;quot;tags&amp;quot;: [     &lt;br /&gt;        &amp;quot;primary&amp;quot;     &lt;br /&gt;      ],     &lt;br /&gt;      &amp;quot;address&amp;quot;: &amp;quot;172.17.0.5&amp;quot;,     &lt;br /&gt;      &amp;quot;port&amp;quot;: 5000,     &lt;br /&gt;      &amp;quot;checks&amp;quot;: [     &lt;br /&gt;        {     &lt;br /&gt;        &amp;quot;http&amp;quot;: &amp;quot;http://localhost:5000/&amp;quot;,     &lt;br /&gt;        &amp;quot;tls_skip_verify&amp;quot;: false,     &lt;br /&gt;        &amp;quot;method&amp;quot;: &amp;quot;Get&amp;quot;,     &lt;br /&gt;        &amp;quot;interval&amp;quot;: &amp;quot;10s&amp;quot;,     &lt;br /&gt;        &amp;quot;timeout&amp;quot;: &amp;quot;1s&amp;quot;     &lt;br /&gt;        }     &lt;br /&gt;      ]     &lt;br /&gt;    }     &lt;br /&gt;  ]     &lt;br /&gt;}     &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;p&gt;复制到consul config目录：&lt;/p&gt; &lt;table&gt;  &lt;tr&gt;   &lt;td&gt;    &lt;pre&gt;docker cp {这里请替换成services.json的本地路径} consul4:/consul/config     &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;p&gt;重新加载consul配置：&lt;/p&gt; &lt;table&gt;  &lt;tr&gt;   &lt;td&gt;    &lt;pre&gt;consul reload     &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;p&gt;然后这个服务就注册成功了。可以将这个服务部署到多个节点，比如部署到consul1和consul4，并同时运行。&lt;/p&gt; &lt;p&gt;  &lt;img alt="" src="http://blog.didispace.com/images/pasted-127.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;h4&gt;  &lt;a href="http://blog.didispace.com/#&amp;#26381;&amp;#21153;&amp;#21457;&amp;#29616;" title="&amp;#26381;&amp;#21153;&amp;#21457;&amp;#29616;"&gt;&lt;/a&gt;服务发现&lt;/h4&gt; &lt;p&gt;服务注册成功以后，调用方获取相应服务地址的过程就是服务发现。Consul提供了多种方式。&lt;/p&gt; &lt;p&gt;  &lt;strong&gt;HTTP API方式：&lt;/strong&gt;&lt;/p&gt; &lt;table&gt;  &lt;tr&gt;   &lt;td&gt;    &lt;pre&gt;curl http://127.0.0.1:8500/v1/health/service/hello?passing=false     &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;p&gt;返回的信息包括注册的Consul节点信息、服务信息及服务的健康检查信息。这里用了一个参数passing=false，会自动过滤掉不健康的服务，包括本身不健康的服务和不健康的Consul节点上的服务，从这个设计上可以看出Consul将服务的状态绑定到了节点的状态。&lt;/p&gt; &lt;p&gt;如果服务有多个部署，会返回服务的多条信息，调用方需要决定使用哪个部署，常见的可以随机或者轮询。为了提高服务吞吐量，以及减轻Consul的压力，还可以缓存获取到的服务节点信息，不过要做好容错的方案，因为缓存服务部署可能会变得不可用。具体是否缓存需要结合自己的访问量及容错规则来确定。&lt;/p&gt; &lt;p&gt;上边的参数passing默认为false，也就是说不健康的节点也会返回，结合获取节点全部服务的方法，这里可以做到获取全部服务的实时健康状态，并对不健康的服务进行报警处理。&lt;/p&gt; &lt;p&gt;  &lt;strong&gt;DNS方式：&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;hello服务的域名是：hello.service.dc1.consul，后边的service代表服务，固定；dc1是数据中心的名字，可以配置；最后的consul也可以配置。&lt;/p&gt; &lt;p&gt;官方在介绍DNS方式时经常使用dig命令进行测试，但是alpine系统中没有dig命令，也没有相关的包可以安装，但是有人实现了，下载下来解压到bin目录就可以了。&lt;/p&gt; &lt;table&gt;  &lt;tr&gt;   &lt;td&gt;    &lt;pre&gt;curl -L https://github.com/sequenceiq/docker-alpine-dig/releases/download/v9.10.2/dig.tgz\|tar -xzv -C /usr/local/bin     &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;p&gt;然后执行dig命令：&lt;/p&gt; &lt;table&gt;  &lt;tr&gt;   &lt;td&gt;    &lt;pre&gt;dig @127.0.0.1 -p 8600 hello.service.dc1.consul. ANY     &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;p&gt;如果报错：  &lt;em&gt;parse of /etc/resolv.conf failed&lt;/em&gt; ，请将resolv.conf中的search那行删掉。&lt;/p&gt; &lt;p&gt;正常的话可以看到返回了服务部署的IP信息，如果有多个部署会看到多个，如果某个部署不健康了会自动剔除（包括部署所在节点不健康的情况）。需要注意这种方式不会返回服务的端口信息。&lt;/p&gt; &lt;p&gt;使用DNS的方式可以在程序中集成一个DNS解析库，也可以自定义本地的DNS Server。自定义本地DNS Server是指将.consul域的请求全部转发到Consul Agent，Windows上有  &lt;a href="https://github.com/stackia/DNSAgent" rel="noopener" target="_blank"&gt;DNS Agent&lt;/a&gt;，Linux上有Dnsmasq；对于非Consul提供的服务则继续请求原DNS；使用DNS Server时Consul会随机返回具体服务的多个部署中的一个，仅能提供简单的负载均衡。&lt;/p&gt; &lt;p&gt;DNS缓存问题：DNS缓存一般存在于应用程序的网络库、本地DNS客户端或者代理，Consul Sever本身可以认为是没有缓存的（为了提高集群DNS吞吐量，可以设置使用普通Server上的陈旧数据，但影响一般不大），DNS缓存可以减轻Consul Server的访问压力，但是也会导致访问到不可用的服务。使用时需要根据实际访问量和容错能力确定DNS缓存方案。&lt;/p&gt; &lt;p&gt;  &lt;strong&gt;Consul Template&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Consul Template是Consul官方提供的一个工具，严格的来说不是标准的服务发现方式。这个工具会通过Consul监听数据变化然后替换模板中使用的标签，并发布替换后的文件到指定的目录。在nginx等web服务器做反向代理和负载均衡时特别有用。&lt;/p&gt; &lt;p&gt;Consul的docker镜像中没有集成这个工具，需要自己安装，比较简单：&lt;/p&gt; &lt;table&gt;  &lt;tr&gt;   &lt;td&gt;    &lt;pre&gt;curl -L https://releases.hashicorp.com/consul-template/0.19.5/consul-template_0.19.5_linux_amd64.tgz\|tar -xzv -C /usr/local/bin     &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;p&gt;然后创建一个文件：in.tpl，内容为：&lt;/p&gt; &lt;table&gt;  &lt;tr&gt;   &lt;td&gt;    &lt;pre&gt;{{ range service &amp;quot;hello&amp;quot; }}     &lt;br /&gt;server {{ .Name }}{{ .Address }}:{{ .Port }}{{ end }}     &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;p&gt;这个标签会遍历hello服务的所有部署，并按照指定的格式输出。在此文件目录下执行：&lt;/p&gt; &lt;table&gt;  &lt;tr&gt;   &lt;td&gt;    &lt;pre&gt;nohup consul-template -template &amp;quot;in.tpl:out.txt&amp;quot; &amp;amp;     &lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;p&gt;现在你可以cat out.txt查看根据模板生产的内容，新增或者关闭服务，文件内容会自动更新。&lt;/p&gt; &lt;p&gt;此工具我没有用在生产环境，详细使用请访问：  &lt;a href="https://github.com/hashicorp/consul-template" rel="noopener" target="_blank"&gt;https://github.com/hashicorp/consul-template&lt;/a&gt;&lt;/p&gt; &lt;h4&gt;  &lt;a href="http://blog.didispace.com/#&amp;#33410;&amp;#28857;&amp;#21644;&amp;#26381;&amp;#21153;&amp;#27880;&amp;#38144;" title="&amp;#33410;&amp;#28857;&amp;#21644;&amp;#26381;&amp;#21153;&amp;#27880;&amp;#38144;"&gt;&lt;/a&gt;节点和服务注销&lt;/h4&gt; &lt;p&gt;节点和服务的注销可以使用HTTP API:&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;注销任意节点和服务：/catalog/deregister&lt;/li&gt;  &lt;li&gt;注销当前节点的服务：/agent/service/deregister/:service_id&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;注意：&lt;/p&gt; &lt;p&gt;如果注销的服务还在运行，则会再次  &lt;a href="https://www.consul.io/docs/internals/anti-entropy.html" rel="noopener" target="_blank"&gt;同步到catalog中&lt;/a&gt;，因此应该只在agent不可用时才使用catalog的注销API。&lt;/p&gt; &lt;p&gt;节点在宕机时状态会变为failed，默认情况下72小时后会被从集群移除。&lt;/p&gt; &lt;p&gt;如果某个节点不继续使用了，也可以在本机使用  &lt;em&gt;consul leave&lt;/em&gt;命令，或者在其它节点使用  &lt;em&gt;consul force-leave 节点Id&lt;/em&gt;，则节点上的服务和健康检查全部注销。&lt;/p&gt; &lt;h3&gt;  &lt;a href="http://blog.didispace.com/#Consul&amp;#30340;&amp;#20581;&amp;#24247;&amp;#26816;&amp;#26597;" title="Consul&amp;#30340;&amp;#20581;&amp;#24247;&amp;#26816;&amp;#26597;"&gt;&lt;/a&gt;Consul的健康检查&lt;/h3&gt; &lt;p&gt;Consul做服务发现是专业的，健康检查是其中一项必不可少的功能，其提供Script/TCP/HTTP+Interval，以及TTL等多种方式。服务的健康检查由服务注册到的Agent来处理，这个Agent既可以是Client也可以是Server。&lt;/p&gt; &lt;p&gt;很多同学都使用ZooKeeper或者etcd做服务发现，使用Consul时发现节点挂掉后服务的状态变为不可用了，所以有同学问服务为什么不在各个节点之间同步？这个根本原因是服务发现的实现原理不同。&lt;/p&gt; &lt;p&gt;  &lt;strong&gt;Consul与ZooKeeper、etcd的区别&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;后边这两个工具是通过键值存储来实现服务的注册与发现。&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;ZooKeeper利用临时节点的机制，业务服务启动时创建临时节点，节点在服务就在，节点不存在服务就不存在。&lt;/li&gt;  &lt;li&gt;etcd利用TTL机制，业务服务启动时创建键值对，定时更新ttl，ttl过期则服务不可用。&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;ZooKeeper和etcd的键值存储都是强一致性的，也就是说键值对会自动同步到多个节点，只要在某个节点上存在就可以认为对应的业务服务是可用的。&lt;/p&gt; &lt;p&gt;Consul的数据同步也是强一致性的，服务的注册信息会在Server节点之间同步，相比ZK、etcd，服务的信息还是持久化保存的，即使服务部署不可用了，仍旧可以查询到这个服务部署。但是业务服务的可用状态是由注册到的Agent来维护的，Agent如果不能正常工作了，则无法确定服务的真实状态，并且Consul是相当稳定了，Agent挂掉的情况下大概率服务器的状态也可能是不好的，此时屏蔽掉此节点上的服务是合理的。Consul也确实是这样设计的，DNS接口会自动屏蔽挂掉节点上的服务，HTTP API也认为挂掉节点上的服务不是passing的。&lt;/p&gt; &lt;p&gt;鉴于Consul健康检查的这种机制，同时避免单点故障，所有的业务服务应该部署多份，并注册到不同的Consul节点。部署多份可能会给你的设计带来一些挑战，因为调用方同时访问多个服务实例可能会由于会话不共享导致状态不一致，这个有许多成熟的解决方案，可以去查询，这里不做说明。&lt;/p&gt; &lt;p&gt;  &lt;strong&gt;健康检查能不能支持故障转移？&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;上边提到健康检查是由服务注册到的Agent来处理的，那么如果这个Agent挂掉了，会不会有别的Agent来接管健康检查呢？答案是否定的。&lt;/p&gt; &lt;p&gt;从问题产生的原因来看，在应用于生产环境之前，肯定需要对各种场景进行测试，没有问题才会上线，所以显而易见的问题可以屏蔽掉；如果是新版本Consul的BUG导致的，此时需要降级；如果这个BUG是偶发的，那么只需要将Consul重新拉起来就可以了，这样比较简单；如果是硬件、网络或者操作系统故障，那么节点上服务的可用性也很难保障，不需要别的Agent接管健康检查。&lt;/p&gt; &lt;p&gt;从实现上看，选择哪个节点是个问题，这需要实时或准实时同步各个节点的负载状态，而且由于业务服务运行状态多变，即使当时选择出了负载比较轻松的节点，无法保证某个时段任务又变得繁重，可能造成新的更大范围的崩溃。如果原来的节点还要启动起来，那么接管的健康检查是否还要撤销，如果要，需要记录服务们最初注册的节点，然后有一个监听机制来触发，如果不要，通过服务发现就会获取到很多冗余的信息，并且随着时间推移，这种数据会越来越多，系统变的无序。&lt;/p&gt; &lt;p&gt;从实际应用看，节点上的服务可能既要被发现，又要发现别的服务，如果节点挂掉了，仅提供被发现的功能实际上服务还是不可用的。当然发现别的服务也可以不使用本机节点，可以通过访问一个Nginx实现的若干Consul节点的负载均衡来实现，这无疑又引入了新的技术栈。&lt;/p&gt; &lt;p&gt;如果不是上边提到的问题，或者你可以通过一些方式解决这些问题，健康检查接管的实现也必然是比较复杂的，因为分布式系统的状态同步是比较复杂的。同时不要忘了服务部署了多份，挂掉一个不应该影响系统的快速恢复，所以没必要去做这个接管。&lt;/p&gt; &lt;h3&gt;  &lt;a href="http://blog.didispace.com/#Consul&amp;#30340;&amp;#20854;&amp;#23427;&amp;#37096;&amp;#32626;&amp;#26550;&amp;#26500;" title="Consul&amp;#30340;&amp;#20854;&amp;#23427;&amp;#37096;&amp;#32626;&amp;#26550;&amp;#26500;"&gt;&lt;/a&gt;Consul的其它部署架构&lt;/h3&gt; &lt;p&gt;如果你实在不想在每个主机部署Consul Client，还有一个多路注册的方案可供选择，这是交流群中获得的思路。&lt;/p&gt; &lt;p&gt;  &lt;img alt="" src="http://blog.didispace.com/images/pasted-128.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;p&gt;如图所示，在专门的服务器上部署Consul Client，然后每个服务都注册到多个Client，这里为了避免服务单点问题还是每个服务部署多份，需要服务发现时，程序向一个提供负载均衡的程序发起请求，该程序将请求转发到某个Consul Client。这种方案需要注意将Consul的8500端口绑定到私网IP上，默认只有127.0.0.1。&lt;/p&gt; &lt;p&gt;这个架构的优势：&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Consul节点服务器与应用服务器隔离，互相干扰少；&lt;/li&gt;  &lt;li&gt;不用每台主机都部署Consul，方便Consul的集中管理；&lt;/li&gt;  &lt;li&gt;某个Consul Client挂掉的情况下，注册到其上的服务仍有机会被访问到；&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;但也需要注意其缺点：&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;引入更多技术栈：负载均衡的实现，不仅要考虑Consul Client的负载均衡，还要考虑负载均衡本身的单点问题。&lt;/li&gt;  &lt;li&gt;Client的节点数量：单个Client如果注册的服务太多，负载较重，需要有个算法（比如hash一致）合理分配每个Client上的服务数量，以及确定Client的总体数量。&lt;/li&gt;  &lt;li&gt;服务发现要过滤掉重复的注册，因为注册到了多个节点会认为是多个部署（DNS接口不会有这个问题）。&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;这个方案其实还可以优化，服务发现使用的负载均衡可以直接代理Server节点，因为相关请求还是会转发到Server节点，不如直接就发到Server。&lt;/p&gt; &lt;p&gt;  &lt;strong&gt;是否可以只有Server？&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;这个问题的答案还是有关服务数量的问题，首先Server的节点数量不是越多越好，3个或者5个是推荐的数量，数量越多数据同步的处理越慢（强一致性）；然后每个节点可以注册的服务数量是有上限的，这个受限于软硬件的处理能力。所以如果你的服务只有10个左右，只有Server问题是不大的，但是这时候有没有必要使用Consul呢？因此正常使用Consul的时候还是要有Client才好，这也符合Consul的反熵设计。&lt;/p&gt; &lt;p&gt;大家可以将这个部署架构与前文提到的普适架构对比下，看看哪个更适合自己，或者你有更好的方案欢迎分享出来。&lt;/p&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>摘抄笔记 微服务 Consul 转载</category>
      <guid isPermaLink="true">https://itindex.net/detail/58972-consul-%E6%9C%8D%E5%8A%A1-%E5%8F%91%E7%8E%B0</guid>
      <pubDate>Sat, 17 Nov 2018 21:21:00 CST</pubDate>
    </item>
    <item>
      <title>【编辑推荐】无区块的区块链，正在成为未来</title>
      <link>https://itindex.net/detail/58635-%E7%BC%96%E8%BE%91-%E5%8C%BA%E5%9D%97%E9%93%BE-%E6%9C%AA%E6%9D%A5</link>
      <description>&lt;img alt="IMG_2920" height="720" src="http://www.bukop.com/wp-content/uploads/2018/08/IMG_2920.jpg" width="960"&gt;&lt;/img&gt; &lt;p&gt;&lt;/p&gt;
 &lt;p&gt;导读：朱嘉明老师是中国改革四君子（王岐山、朱嘉明、黄江南、翁永曦）之一，知名经济学家。上世纪八十年代初中国对社会变革的期待如火山喷发，力量积蓄已久，社会潮流惟以“变”字当道，政治新锐先发制人，应时而生的“改革四君子”至今仍影响中国社会进程。六哥在今年年初有幸结识朱嘉明老师跟随学习，并且在朱老师的言传身教下开始研究区块链，随着思考的深入，从最初本能的拒绝到现在坚定的拥抱，完成了认知的艰难升级，成为区块链的信仰者。未来的区块链和加密数字货币的思想、技术和组织，正在决定和改变着人类经济生活和政治生活，我们正身在其中。朱老师认为，在未来的10年里，区块链技术将会成为一种破坏性的技术类挑战和颠覆原有商业与生产模式，但是这样的技术和它的应用仍处于非常初级的阶段。本篇重点探讨区块链的创新路径及未来趋势，  &lt;strong&gt;当前的区块链是基于数论的区块链，未来创新的方向则是基于拓扑学的区块链，没有区块的区块链&lt;/strong&gt;，值得认真思考。&lt;/p&gt;



 &lt;p&gt;&lt;/p&gt;





 &lt;strong&gt;现阶段区块链存在怎样的创新路径？区块链过去、现在和未来的生命力，都决定于其“创新”能力。区块链的创新主要是两类：在现阶段区块链主流架构下的创新，以及从本源上突破了主流框架的创新。&lt;/strong&gt; &lt;p&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;基于区块主流架构的创新&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;現在普遍看法是，比特币是区块链的1.0, 以太坊是区块链的2.0。但是，不论是比特币，还是以太坊所代表的区块链，都是“公有链“的主流框架。在主流框架下的“创新”主要集中在：&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;其一，突破“可扩展性”限制。&lt;/strong&gt;主要包括比特币通过“分叉”的扩容方案，以太坊自身的Plasma，State Channel, Raiden，Truebit，Sharding，Casper等扩容方案；以及诸如侧链技术（Rootstock, Polkadot, Cosmos），区块扩容，链下计算，分区共识，分片的 “内部分割”等处于试验阶段的选择方案。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;其二，改善“存储”。&lt;/strong&gt;工程实例至少有：Swarm（以太坊的P2P文件共享协议），Storj（一种“分布式存储“），以及IPFS（一种P2P超媒体协议）。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;其三，EOS代表的区块链操作系统。&lt;/strong&gt;根据EOS白皮书显示，其预计扩展至单链几千TPS、全网并行百万TPS的交易吞吐量，并且主网已于2018年6月上线，是未来区块链平台强有力的竞争者。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;其四，开发具有隐私和法规的区块链。&lt;/strong&gt;例如 Cardano。Cardano是世界上第一个由研究为主导，从科学哲学开发出来的区块链项目，也是第一个采用同行评审技术的区块链项目，可用于发送和接收数字资金，支持各种去中心化应用和智能合约。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;其五，提高智能合约的安全性。&lt;/strong&gt;一个被称之为“形式化验证”的技术，正在逐步应用到区块链智能合约代码检查。其原理是，根据某个或某些形式规范或属性，使用数学的方法证明其正确性或非正确性。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;其六，满足区块链测试需求&lt;/strong&gt;，完善参考“ISO/IEC 25010标准”的一个测试模型。在这个模型中，区块链评测涉及到8个维度，进而延伸出31个分维度。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;突破现阶段区块链主流架构的创新&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;必须注意到，在区块链主流架构下的创新，只具有相对意义。例如，比特币在理论上可逆，在顶层设计阶段就没有彻底解决共识问题，只是将问题加以转换，“一方面通过区块链的序号作为虚拟时间，一方面通过“挖矿”的经济动力来促使比特币链的不断延伸”。 在这个意义上，中本聪用此类经济方法解决分布式系统共识算法，确实相当智慧。进一步说，现阶段的区块链，难以升级。一旦区块链被部署和进入生产模式，在功能上进行添加、修改和删除，难度甚大，成本甚高。 现在，通常的区块链修改，都会造成区块链系统的软分叉或者硬分叉，造成大量的时间和能量精力投入，且承受由此带来的经济后果。&lt;/p&gt;
 &lt;p&gt;所以，区块链的真正创新必须突破主流架构，实现顶层理论设计和数学方法上的创新。这种突破主流框架的创新，已经悄然开始。到目前为止，DAG (Directed Acyclic Graph)，即有向无环图，属于突破现阶段区块链主流架构的创新。“比特币的效率一直比较低，基于工作量证明共识下的出块机制是一个原因，由于链式的存储结构，整个网络中同时只能有一条链，导致出块无法并发执行。DAG从根本上摒弃了区块概念，交易直接进入全网中，达到所谓的“无区块（Blockless）”效果，网络中的交易就可以容纳N倍。”&lt;/p&gt;
 &lt;p&gt;具体说，DAG有四个特点：&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;其一，交易速度快&lt;/strong&gt;，交易速度远远高于基于POW和POS的区块链交易速度。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;其二，无需挖矿&lt;/strong&gt;：DAG把交易确认的环境直接下放给交易本身，无需由矿工打包成区块后同意交易顺序。所以DAG网络中没有矿工的角色。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;其三，无手续费&lt;/strong&gt;：交易发起只需要做简单的POW工作量证明，整个网络中的POW都是发起交易者自己做的，而不是交给矿工。发起交易无需手续费。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;其四，需要见证节点&lt;/strong&gt;：DAG需要见证人机制的存在。超越DPOS、POS、PBFT，最终实现在效率与安全性的一种平衡。DAG的数学基础不再是数论，而是图论，即拓扑学，即以空间、维度与变换作为研究对象的学科。图论原理显然更接近对区块链基本模式的描述。DAG模式如下：&lt;/p&gt;




 &lt;img alt="640" height="324" src="http://www.bukop.com/wp-content/uploads/2018/08/640.png" width="324"&gt;&lt;/img&gt;








第一次提出DAG跟区块链结合是在Nxt社区，该社区的成员大多集中在东欧和俄罗斯，去中心化对他们更具有现实意义。 &lt;p&gt;&lt;/p&gt;
 &lt;p&gt;现在，基于DAG原理和技术的IOTA，由四名平均年龄不到30岁、最年轻者仅21岁的团队所创立，推出不到两年，其价格在虚拟货币中已经攀升至第八名，他们更高的目标是成为“物联网”的骨干。&lt;/p&gt;
 &lt;p&gt;此外，Swirlds公司开发的Hashgraph技术也是DAG结构的一种。Hashgraph通过“Gossip about Gossip”协议，“让每个节点都维护着所有节点跟其他节点的通信历史，每个节点在完成拜占庭协议时，不需要经过网络多轮通讯，节点本地环境就可以直接模拟拜占庭决议。Hashgraph的数学上可以证明满足异步拜占庭容错，至少跟比特币一样安全。” 不过，对于Hashgraph技术，尚有很大争议。&lt;/p&gt;

 &lt;p&gt;————————&lt;/p&gt;
 &lt;p&gt;「加密笔记」 CryptoNote是由「商业不靠谱 www.bukop.com」的主编六哥所发起的区块链创业主题自媒体。 我们秉持一贯的内容主张，不追求点击率，只追求点醒率：点醒读者的几率。&lt;/p&gt;
 &lt;p&gt;想要深入了解区块链和加密经济，长按下面二维码关注“加密笔记”&lt;/p&gt;
 &lt;p&gt;  &lt;img src="http://www.bukop.com/wp-content/uploads/2018/08/qr.jpg"&gt;&lt;/img&gt; 微信扫一扫  &lt;br /&gt;
关注”加密笔记”&lt;/p&gt;





&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>区块链 大师智慧 加密笔记 比特币</category>
      <guid isPermaLink="true">https://itindex.net/detail/58635-%E7%BC%96%E8%BE%91-%E5%8C%BA%E5%9D%97%E9%93%BE-%E6%9C%AA%E6%9D%A5</guid>
      <pubDate>Mon, 20 Aug 2018 00:20:14 CST</pubDate>
    </item>
    <item>
      <title>从零开始的Spring Session(二)</title>
      <link>https://itindex.net/detail/57427-%E4%BB%8E%E9%9B%B6%E5%BC%80%E5%A7%8B-spring-session</link>
      <description>&lt;p&gt;上一篇文章介绍了一些Session和Cookie的基础知识，这篇文章开始正式介绍Spring Session是如何对传统的Session进行改造的。官网这么介绍Spring Session：&lt;/p&gt;
 &lt;blockquote&gt;
  &lt;p&gt;Spring Session provides an API and implementations for managing a user’s session information. It also provides transparent integration with:&lt;/p&gt;
  &lt;ul&gt;
   &lt;li&gt;    &lt;a href="https://docs.spring.io/spring-session/docs/1.3.1.RELEASE/reference/html5/#httpsession" rel="external" target="_blank"&gt;HttpSession&lt;/a&gt; - allows replacing the HttpSession in an application container (i.e. Tomcat) neutral way. Additional features include:    &lt;ul&gt;
     &lt;li&gt;      &lt;strong&gt;Clustered Sessions&lt;/strong&gt; - Spring Session makes it trivial to support       &lt;a href="https://docs.spring.io/spring-session/docs/1.3.1.RELEASE/reference/html5/#httpsession-redis" rel="external" target="_blank"&gt;clustered sessions&lt;/a&gt; without being tied to an application container specific solution.&lt;/li&gt;
     &lt;li&gt;      &lt;strong&gt;Multiple Browser Sessions&lt;/strong&gt; - Spring Session supports       &lt;a href="https://docs.spring.io/spring-session/docs/1.3.1.RELEASE/reference/html5/#httpsession-multi" rel="external" target="_blank"&gt;managing multiple users’ sessions&lt;/a&gt; in a single browser instance (i.e. multiple authenticated accounts similar to Google).&lt;/li&gt;
     &lt;li&gt;      &lt;strong&gt;RESTful APIs&lt;/strong&gt; - Spring Session allows providing session ids in headers to work with       &lt;a href="https://docs.spring.io/spring-session/docs/1.3.1.RELEASE/reference/html5/#httpsession-rest" rel="external" target="_blank"&gt;RESTful APIs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
   &lt;li&gt;    &lt;a href="https://docs.spring.io/spring-session/docs/1.3.1.RELEASE/reference/html5/#websocket" rel="external" target="_blank"&gt;WebSocket&lt;/a&gt; - provides the ability to keep the     &lt;code&gt;HttpSession&lt;/code&gt; alive when receiving WebSocket messages&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
 &lt;p&gt;其具体的特性非常之多，具体的内容可以从文档中了解到，笔者做一点自己的总结，Spring Session的特性包括但不限于以下：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;使用GemFire来构建C/S架构的httpSession（不关注）&lt;/li&gt;
  &lt;li&gt;使用第三方仓储来实现集群session管理，也就是常说的分布式session容器，替换应用容器（如tomcat的session容器）。仓储的实现，Spring Session提供了三个实现（redis，mongodb，jdbc），其中redis使我们最常用的。程序的实现，使用AOP技术，几乎可以做到透明化地替换。（核心）&lt;/li&gt;
  &lt;li&gt;可以非常方便的扩展Cookie和自定义Session相关的Listener，Filter。&lt;/li&gt;
  &lt;li&gt;可以很方便的与Spring Security集成，增加诸如findSessionsByUserName，rememberMe，限制同一个账号可以同时在线的Session数（如设置成1，即可达到把前一次登录顶掉的效果）等等&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;介绍完特性，下面开始一步步集成Spring Session&lt;/p&gt;
 &lt;h2&gt;  &lt;a href="http://blog.didispace.com/#&amp;#20351;&amp;#29992;Redis&amp;#38598;&amp;#25104;Spring-Session" title="&amp;#20351;&amp;#29992;Redis&amp;#38598;&amp;#25104;Spring Session"&gt;&lt;/a&gt;使用Redis集成Spring Session&lt;/h2&gt; &lt;ul&gt;
  &lt;li&gt;引入依赖，Spring Boot的版本采用1.5.4&lt;/li&gt;
&lt;/ul&gt;
 &lt;table&gt;  &lt;tr&gt;   &lt;td&gt;    &lt;pre&gt;     &lt;div&gt;1&lt;/div&gt;     &lt;div&gt;2&lt;/div&gt;     &lt;div&gt;3&lt;/div&gt;     &lt;div&gt;4&lt;/div&gt;     &lt;div&gt;5&lt;/div&gt;     &lt;div&gt;6&lt;/div&gt;     &lt;div&gt;7&lt;/div&gt;     &lt;div&gt;8&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;   &lt;td&gt;    &lt;pre&gt;     &lt;div&gt;&amp;lt;dependency&amp;gt;&lt;/div&gt;     &lt;div&gt;    &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;&lt;/div&gt;     &lt;div&gt;    &amp;lt;artifactId&amp;gt;spring-boot-starter-web&amp;lt;/artifactId&amp;gt;&lt;/div&gt;     &lt;div&gt;&amp;lt;/dependency&amp;gt;&lt;/div&gt;     &lt;div&gt;&amp;lt;dependency&amp;gt;&lt;/div&gt;     &lt;div&gt;    &amp;lt;groupId&amp;gt;org.springframework.session&amp;lt;/groupId&amp;gt;&lt;/div&gt;     &lt;div&gt;    &amp;lt;artifactId&amp;gt;spring-session-data-redis&amp;lt;/artifactId&amp;gt;&lt;/div&gt;     &lt;div&gt;&amp;lt;/dependency&amp;gt;&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
 &lt;ul&gt;
  &lt;li&gt;配置&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;配置类开启Redis Http Session&lt;/p&gt;
 &lt;table&gt;  &lt;tr&gt;   &lt;td&gt;    &lt;pre&gt;     &lt;div&gt;1&lt;/div&gt;     &lt;div&gt;2&lt;/div&gt;     &lt;div&gt;3&lt;/div&gt;     &lt;div&gt;4&lt;/div&gt;     &lt;div&gt;5&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;   &lt;td&gt;    &lt;pre&gt;     &lt;div&gt;@Configuration&lt;/div&gt;     &lt;div&gt;@EnableRedisHttpSession&lt;/div&gt;     &lt;div&gt;public class HttpSessionConfig {&lt;/div&gt;     &lt;div&gt;&lt;/div&gt;     &lt;div&gt;}&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
 &lt;p&gt;基本是0配置，只需要让主配置扫描到@EnableRedisHttpSession即可&lt;/p&gt;
 &lt;p&gt;配置文件application.yml，配置连接的redis信息&lt;/p&gt;
 &lt;table&gt;  &lt;tr&gt;   &lt;td&gt;    &lt;pre&gt;     &lt;div&gt;1&lt;/div&gt;     &lt;div&gt;2&lt;/div&gt;     &lt;div&gt;3&lt;/div&gt;     &lt;div&gt;4&lt;/div&gt;     &lt;div&gt;5&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;   &lt;td&gt;    &lt;pre&gt;     &lt;div&gt;spring:&lt;/div&gt;     &lt;div&gt;  redis:&lt;/div&gt;     &lt;div&gt;    host: localhost&lt;/div&gt;     &lt;div&gt;    port: 6379&lt;/div&gt;     &lt;div&gt;    database: 0&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
 &lt;ul&gt;
  &lt;li&gt;编写测试Controller，以便于观察Spring Session的特性，和前一篇文章使用同样的代码&lt;/li&gt;
&lt;/ul&gt;
 &lt;table&gt;  &lt;tr&gt;   &lt;td&gt;    &lt;pre&gt;     &lt;div&gt;1&lt;/div&gt;     &lt;div&gt;2&lt;/div&gt;     &lt;div&gt;3&lt;/div&gt;     &lt;div&gt;4&lt;/div&gt;     &lt;div&gt;5&lt;/div&gt;     &lt;div&gt;6&lt;/div&gt;     &lt;div&gt;7&lt;/div&gt;     &lt;div&gt;8&lt;/div&gt;     &lt;div&gt;9&lt;/div&gt;     &lt;div&gt;10&lt;/div&gt;     &lt;div&gt;11&lt;/div&gt;     &lt;div&gt;12&lt;/div&gt;     &lt;div&gt;13&lt;/div&gt;     &lt;div&gt;14&lt;/div&gt;     &lt;div&gt;15&lt;/div&gt;     &lt;div&gt;16&lt;/div&gt;     &lt;div&gt;17&lt;/div&gt;     &lt;div&gt;18&lt;/div&gt;     &lt;div&gt;19&lt;/div&gt;     &lt;div&gt;20&lt;/div&gt;     &lt;div&gt;21&lt;/div&gt;     &lt;div&gt;22&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;   &lt;td&gt;    &lt;pre&gt;     &lt;div&gt;@Controller&lt;/div&gt;     &lt;div&gt;public class CookieController {&lt;/div&gt;     &lt;div&gt;&lt;/div&gt;     &lt;div&gt;    @RequestMapping(&amp;quot;/test/cookie&amp;quot;)&lt;/div&gt;     &lt;div&gt;    public String cookie(@RequestParam(&amp;quot;browser&amp;quot;) String browser, HttpServletRequest request, HttpSession session) {&lt;/div&gt;     &lt;div&gt;        //取出session中的browser&lt;/div&gt;     &lt;div&gt;        Object sessionBrowser = session.getAttribute(&amp;quot;browser&amp;quot;);&lt;/div&gt;     &lt;div&gt;        if (sessionBrowser == null) {&lt;/div&gt;     &lt;div&gt;            System.out.println(&amp;quot;不存在session，设置browser=&amp;quot; + browser);&lt;/div&gt;     &lt;div&gt;            session.setAttribute(&amp;quot;browser&amp;quot;, browser);&lt;/div&gt;     &lt;div&gt;        } else {&lt;/div&gt;     &lt;div&gt;            System.out.println(&amp;quot;存在session，browser=&amp;quot; + sessionBrowser.toString());&lt;/div&gt;     &lt;div&gt;        }&lt;/div&gt;     &lt;div&gt;        Cookie[] cookies = request.getCookies();&lt;/div&gt;     &lt;div&gt;        if (cookies != null &amp;amp;&amp;amp; cookies.length &amp;gt; 0) {&lt;/div&gt;     &lt;div&gt;            for (Cookie cookie : cookies) {&lt;/div&gt;     &lt;div&gt;                System.out.println(cookie.getName() + &amp;quot; : &amp;quot; + cookie.getValue());&lt;/div&gt;     &lt;div&gt;            }&lt;/div&gt;     &lt;div&gt;        }&lt;/div&gt;     &lt;div&gt;        return &amp;quot;index&amp;quot;;&lt;/div&gt;     &lt;div&gt;    }&lt;/div&gt;     &lt;div&gt;}&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
 &lt;p&gt;启动类省略，下面开始测试。&lt;/p&gt;
 &lt;p&gt;在浏览器中访问如下端点：  &lt;code&gt;http://localhost:8080/test/cookie?browser=chrome&lt;/code&gt;，下面是连续访问4次的结果&lt;/p&gt;
 &lt;table&gt;  &lt;tr&gt;   &lt;td&gt;    &lt;pre&gt;     &lt;div&gt;1&lt;/div&gt;     &lt;div&gt;2&lt;/div&gt;     &lt;div&gt;3&lt;/div&gt;     &lt;div&gt;4&lt;/div&gt;     &lt;div&gt;5&lt;/div&gt;     &lt;div&gt;6&lt;/div&gt;     &lt;div&gt;7&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;   &lt;td&gt;    &lt;pre&gt;     &lt;div&gt;1	不存在session，设置browser=chrome&lt;/div&gt;     &lt;div&gt;2	存在session，browser=chrome&lt;/div&gt;     &lt;div&gt;	SESSION : 70791b17-83e1-42db-8894-73fbd2f2a159&lt;/div&gt;     &lt;div&gt;3	存在session，browser=chrome&lt;/div&gt;     &lt;div&gt;	SESSION : 70791b17-83e1-42db-8894-73fbd2f2a159&lt;/div&gt;     &lt;div&gt;4	存在session，browser=chrome&lt;/div&gt;     &lt;div&gt;	SESSION : 70791b17-83e1-42db-8894-73fbd2f2a159&lt;/div&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
 &lt;p&gt;如果还记得上一篇文章中运行结果的话，会发现和原生的session管理是有一些差别，原先的信息中我们记得Cookie中记录的Key值是JSESSIONID，而替换成RedisHttpSession之后变成了SESSION。接着观察redis中的变化：&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="redis&amp;#20013;&amp;#30340;session" src="http://blog.didispace.com/content/images/posts/spring-session-xjf-2-1.png"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;解析一下这个redis store，如果不纠结于细节，可以跳过，不影响使用。&lt;/p&gt;
 &lt;p&gt;​1 spring:session是默认的Redis HttpSession前缀（redis中，我们常用’:’作为分割符）。&lt;/p&gt;
 &lt;p&gt;2 每一个session都会有三个相关的key，第三个key最为重要，它是一个HASH数据结构，将内存中的session信息序列化到了redis中。如上文的browser，就被记录为sessionAttr:browser=chrome,还有一些meta信息，如创建时间，最后访问时间等。&lt;/p&gt;
 &lt;p&gt;3 另外两个key，expirations:1504446540000和sessions:expires:7079…我发现大多数的文章都没有对其分析，前者是一个SET类型，后者是一个STRING类型，可能会有读者发出这样的疑问，redis自身就有过期时间的设置方式TTL，为什么要额外添加两个key来维持session过期的特性呢？这需要对redis有一定深入的了解才能想到这层设计。当然这不是本节的重点，简单提一下：redis清除过期key的行为是一个异步行为且是一个低优先级的行为，用文档中的原话来说便是，可能会导致session不被清除。于是引入了专门的expiresKey，来专门负责session的清除，包括我们自己在使用redis时也需要关注这一点。在开发层面，我们仅仅需要关注第三个key就行了。&lt;/p&gt;
 &lt;h2&gt;  &lt;a href="http://blog.didispace.com/#&amp;#24635;&amp;#32467;" title="&amp;#24635;&amp;#32467;"&gt;&lt;/a&gt;总结&lt;/h2&gt; &lt;p&gt;本节主要讲解了Spring Boot如何集成Spring Session，下一节将介绍更加复杂的特性。包括自定义Cookie序列化策略，与Spring Security的集成，根据用户名查找session等特性以及使用注意点。&lt;/p&gt;
&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>摘抄笔记 Spring Session 摘抄</category>
      <guid isPermaLink="true">https://itindex.net/detail/57427-%E4%BB%8E%E9%9B%B6%E5%BC%80%E5%A7%8B-spring-session</guid>
      <pubDate>Thu, 07 Sep 2017 01:35:59 CST</pubDate>
    </item>
    <item>
      <title>关于Uber机制的思考</title>
      <link>https://itindex.net/detail/54368-uber-%E6%80%9D%E8%80%83</link>
      <description>&lt;p&gt;昨天写了一篇关于滴滴打车改版的文章（文章链接），引发了一些关于Uber和滴滴的对比讨论。&lt;/p&gt;
 &lt;p&gt;质疑明显歪了楼，大家主要讨论的是，Uber忽略目的地的问题和它的派单机制，而我在昨天文章中说的是Uber的首页设计的一些问题，具体来说，是它的出发地和开始用车的按钮不在一起的问题，以及出发地带搜索icon带来误解的问题。&lt;/p&gt;
 &lt;p&gt;不过既然大家讨论到了Uber的忽略目的地的机制和派单机制，我也就聊聊我的看法。&lt;/p&gt;
 &lt;p&gt;虽然现在Uber因为做出了拼车机制，开始要求输入目的地（许多喜欢Uber的人认为是一种倒退），但Uber此前的理念的确是会刻意忽略目的地的。身边许多朋友，也对这个理念表示认可。因为觉得它可以防止司机挑单。具体是，Uber的机制中，乘客一旦发出请求，附近的一位司机被自动被系统派单，必须前往接驾，否则将被惩罚。我奇怪的地方之一在于，这种派单机制中，即使乘客输入了目的地，不是一样派么？而就算乘客没输入目的地，司机也可以电话问乘客要去哪里，然后也可以根据自己的喜好取消单（这也是现在的现状，当然，有人要说了，他觉得这是在中国，在契约精神很强的国外，司机被派了单是不会被取消的，对于这种想法，我没有什么想说的），这不一样么。&lt;/p&gt;
 &lt;p&gt;话说回来，Uber首页的设计之差，与其机制和思想没什么关系，就是差。就算不想要输入目的地，不想派单，难道就不可以将出发地和发出请求的操作放置到一起么？显然这2个事情是有内在逻辑联系的，但Uber把它一个放在页面顶部，一个放在页面中间，令人费解。&lt;/p&gt;
 &lt;p&gt;关于目的地这件事，它对我个人的其中一个意义是掌控感。我不知道对于别人说是如何，但是对于我，一旦出行，一定是有一个想去的地方，打开出行软件，下意识会想到我肯定要告诉这个软件我要去哪里，这是一种我可以掌控自己去向的感觉，而不是第一次打开Uber，觉得无所适从，因为一开始预期想做的事情（告诉软件我要去哪里）无法做。当然，有人说线下招车也是招到再说目的地，那是因为你没法和还在很远的车里的司机说目的地，这样去招车，对于会挑单的司机，一样会拒单。&lt;/p&gt;
 &lt;p&gt;还有Uber的派单机制。  &lt;strong&gt;派单机制的确让作为乘客的我觉得很有安全感，我作为乘客会继续使用Uber，我也非常清楚Uber的设计理念是希望它的叫车极快，但我仍旧不太认可它的机制设计，担心有一个比较严重的问题。&lt;/strong&gt;就是，因为派单机制对于司机，显然体验是不太好的，或者至少对于滴滴那类可以让司机挑选单的平台来说相对差些。而对于这类资源平台，我认为保住司机比保住乘客更重要，我的这个倾向和我在UGC平台中强烈建议优先考虑内容生产者的体验，是一样的。Uber目前的做法，只能通过对司机的补贴比滴滴多，来决定，换句话说，  &lt;strong&gt;同一个司机，在Uber中必须比在滴滴中赚得多，才会留在Uber。这个根本上的区别，导致对于乘客，不考虑短期的补贴，长远来看，滴滴一定比Uber便宜，也就是说，Uber会相比滴滴更加小众、高端。&lt;/strong&gt;类似一个是大众，一个是宝马，不好说谁输谁赢，但从用户规模、估值规模的角度来说，Uber的模式未来会弱于滴滴的模式。&lt;/p&gt;
 &lt;p&gt;当然，我估计滴滴在一开始做抢单机制而不是派单机制的时候，也不一定想了这么多。我想的这些也不一定对，只是当前阶段我对派单和抢单两种机制的看法。我会继续两者都用，用滴滴是因为发票，以及觉得未来它会更便宜，用Uber是因为相对小众高端，和确定有车的安全感。&lt;/p&gt;
 &lt;p&gt;我都快好像变成Uber黑了，但是实际上我真的非常欣赏共享经济，因为共享经济是解决一个社会性的闲散资源分配不合理的问题，Uber（和Airbnb）算是共享经济的鼻祖。Uber做了许多创新，其中我印象最深刻的一条是在高峰期时通过某个区域内价格增加一个倍数，吸引更多车辆进入热门区域（也直观地让他们了解到哪里是此时的叫车需求多的区域），这对于车辆和乘客来说是双赢（加价会提醒用户），这个优秀的机制果然滴滴就仿照了，这是应该的。&lt;/p&gt;
 &lt;p&gt;关注我的公众号，阅读更多文章：&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://kant.cc/wp-content/uploads/2015/05/&amp;#37049;&amp;#21073;&amp;#27874;Kant&amp;#20108;&amp;#32500;&amp;#30721;.jpg"&gt;   &lt;img alt="&amp;#37049;&amp;#21073;&amp;#27874;Kant&amp;#20108;&amp;#32500;&amp;#30721;" height="258" src="http://kant.cc/wp-content/uploads/2015/05/&amp;#37049;&amp;#21073;&amp;#27874;Kant&amp;#20108;&amp;#32500;&amp;#30721;.jpg" width="258"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>学习笔记 所有文章 Uber 产品设计</category>
      <guid isPermaLink="true">https://itindex.net/detail/54368-uber-%E6%80%9D%E8%80%83</guid>
      <pubDate>Sun, 20 Sep 2015 00:08:27 CST</pubDate>
    </item>
    <item>
      <title>读写模型整理笔记</title>
      <link>https://itindex.net/detail/53302-%E6%A8%A1%E5%9E%8B-%E7%AC%94%E8%AE%B0</link>
      <description>&lt;p&gt;  &lt;strong&gt;读模型&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;1、主键读&lt;/p&gt;
 &lt;p&gt;最常见的读模型，说是主键，其实也包括其它索引键，或者联合主键。&lt;/p&gt;
 &lt;p&gt;常见实现：hash，时间复杂度可以接近O(1)；B树或变种：时间复杂度接近O(log(n))。&lt;/p&gt;
 &lt;p&gt;关于B树和变种：&lt;/p&gt;
 &lt;p&gt;B树（B-树）：本质上是二叉查找树的升级版，变成了平衡的N叉查找树，这个N的范围根据磁盘一次读取的块大小来调整，这样复杂度log n的底数就从2变成一个更大的数，减少了树的高度。除此以外，还有一些额外的优化，比如为了插入和删除的性能考虑，通常准备一些预留的空间，只要在当前块或者邻近块中找到空间写入，就避免了开销巨大的所有记录向后偏移的操作。&lt;/p&gt;
 &lt;p&gt;B树的阶：&lt;/p&gt;
 &lt;ol&gt;
  &lt;li&gt;一棵m阶的B树最多有m棵子树；&lt;/li&gt;
  &lt;li&gt;根节点至少有两棵子树；&lt;/li&gt;
  &lt;li&gt;每个非根分支节点至少有ceil(m/2)棵子树；&lt;/li&gt;
  &lt;li&gt;叶节点全部在同一层；&lt;/li&gt;
  &lt;li&gt;有x个孩子的非叶节点恰有x-1个递增排列的关键字。&lt;/li&gt;
&lt;/ol&gt;
 &lt;p&gt;  &lt;a href="http://www.raychase.net/wp-content/uploads/2015/04/btree.gif"&gt;   &lt;img alt="&amp;#35835;&amp;#20889;&amp;#27169;&amp;#22411;&amp;#25972;&amp;#29702;&amp;#31508;&amp;#35760;" border="0" height="152" src="http://www.raychase.net/wp-content/uploads/2015/04/btree_thumb.gif" title="&amp;#35835;&amp;#20889;&amp;#27169;&amp;#22411;&amp;#25972;&amp;#29702;&amp;#31508;&amp;#35760;" width="453"&gt;&lt;/img&gt;&lt;/a&gt; &lt;/p&gt;
 &lt;p&gt;图片来自  &lt;a href="http://staff.ustc.edu.cn/~csli/graduate/algorithms/book6/chap19.htm" target="_blank"&gt;此页面&lt;/a&gt;。&lt;/p&gt;
 &lt;p&gt;B+树：和B树相比，改变的地方包括：&lt;/p&gt;
 &lt;ol&gt;
  &lt;li&gt;全部关键字信息都放在叶子节点；&lt;/li&gt;
  &lt;li&gt;所有叶子节点串成一个linked list以便搜索；&lt;/li&gt;
  &lt;li&gt;存放重复的搜索键。&lt;/li&gt;
&lt;/ol&gt;
 &lt;p&gt;具体的区别可以参见  &lt;a href="http://www.differencebetween.info/difference-between-b-tree-and-b-plus-tree" target="_blank"&gt;《Difference between B Tree and B+ Tree》&lt;/a&gt;，（下图出处）。&lt;/p&gt;
 &lt;p&gt;  &lt;a href="http://www.raychase.net/wp-content/uploads/2015/04/Btree.jpg"&gt;   &lt;img alt="&amp;#35835;&amp;#20889;&amp;#27169;&amp;#22411;&amp;#25972;&amp;#29702;&amp;#31508;&amp;#35760;" border="0" height="198" src="http://www.raychase.net/wp-content/uploads/2015/04/Btree_thumb.jpg" title="&amp;#35835;&amp;#20889;&amp;#27169;&amp;#22411;&amp;#25972;&amp;#29702;&amp;#31508;&amp;#35760;" width="404"&gt;&lt;/img&gt;&lt;/a&gt; &lt;/p&gt;
 &lt;p&gt;B*树在B+树基础上做了进一步改进：&lt;/p&gt;
 &lt;ol&gt;
  &lt;li&gt;非叶子节点增加指向兄弟节点的指针（用以在节点满时，可以往兄弟节点放数据，减少节点创建的情况）；&lt;/li&gt;
  &lt;li&gt;非叶子节点至少为2/3满的（关键字字数至少为最大值的2/3）。&lt;/li&gt;
&lt;/ol&gt;
 &lt;p&gt;2、指定页查询&lt;/p&gt;
 &lt;p&gt;指定页就意味着具备分页的概念，比如在DynamoDB的查询接口设计上，可以传入一个LastEvaluatedKey这样的对象，通过主键读的方式定位到本页读取的起始位置。但是，如果要随机指定页码号的查询，这种情况的复杂度在不同实现的情况下就有很大差异了，有的可以直接算出该页的位置，有的则需要从第一页开始一页页找下去。&lt;/p&gt;
 &lt;p&gt;常见实现：指定起始位置，条件查询的情况下返回数据子集。&lt;/p&gt;
 &lt;p&gt;3、范围查询&lt;/p&gt;
 &lt;p&gt;首先，数据可以根据某一属性排序，然后才存在范围查询的概念。比如用户的年龄在某个区间之内的查询。&lt;/p&gt;
 &lt;p&gt;常见实现：B树及其变种（这种情况下B+树比B树优越的地方就体现出来了，B+树可以直接扫描叶子节点的linked list即可）。&lt;/p&gt;
 &lt;p&gt;4、全数据扫描&lt;/p&gt;
 &lt;p&gt;这种访问模型通常意味着低速和高开销，一般多用作异步任务，比如报表系统，在低访问时段做定时的数据统计。通常非索引键查询本质上也是全数据扫描。&lt;/p&gt;
 &lt;p&gt;例子：数据库全表扫描，Hadoop上的数据集处理任务。&lt;/p&gt;
 &lt;p&gt;5、全文检索&lt;/p&gt;
 &lt;p&gt;常见实现：倒排索引。&lt;/p&gt;
 &lt;p&gt;6、前缀/后缀匹配&lt;/p&gt;
 &lt;p&gt;前缀匹配：Trie树；后缀匹配：后缀树。参见  &lt;a href="http://www.raychase.net/1783" target="_blank"&gt;《Trie树和其它数据结构的比较》&lt;/a&gt;。&lt;/p&gt;
 &lt;p&gt;7、条件查询&lt;/p&gt;
 &lt;p&gt;常见实现：全表扫描；R树；  &lt;a href="http://en.wikipedia.org/wiki/Space-filling_curve" target="_blank"&gt;Space-filling Curve&lt;/a&gt;。 &lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;写模型&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;1、异步更新&lt;/p&gt;
 &lt;p&gt;先返回，不关注更新的事务性，更新操作在后台完成，这种方式具备最快的结果返回速度。&lt;/p&gt;
 &lt;p&gt;2、队列/双端队列&lt;/p&gt;
 &lt;p&gt;这种情况适用于吞吐量比较大并且非常不稳定的情形，借助队列的缓冲作用；也有一种是需要处理写入次序的问题，借助优先级队列的有序性。&lt;/p&gt;
 &lt;p&gt;3、批量写&lt;/p&gt;
 &lt;p&gt;很多情况下是异步的数据处理，比如数据回填、批量数据导出等等。&lt;/p&gt;
 &lt;p&gt;4、根据查询结果更新&lt;/p&gt;
 &lt;p&gt;就是把查询和更新这两步过程合并，使之具备原子性。比如Java中的compareAndSet操作，比如数据库的update语句跟上where子句等等。&lt;/p&gt;
 &lt;p&gt;5、插入或更新&lt;/p&gt;
 &lt;p&gt;upsert，如同hash map中的put，不管之前该记录是否存在，存在就覆盖，不存在就插入。&lt;/p&gt;
 &lt;p&gt;6、更新到多个replication&lt;/p&gt;
 &lt;p&gt;几乎所有的产品化的存储系统都会考虑replication，对于数据可靠性的问题，软件层面上冗余多份数据是唯一的办法。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;文章未经特殊标明皆为本人原创，未经许可不得用于任何商业用途，转载请保持完整性并注明来源链接   &lt;a href="http://www.raychase.net/2932"&gt;《四火的唠叨》&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;div&gt;分享到：  &lt;a href="javascript:void(0);" title="&amp;#20998;&amp;#20139;&amp;#21040;&amp;#26032;&amp;#28010;"&gt;&lt;/a&gt;  &lt;a href="javascript:void(0);" title="&amp;#20998;&amp;#20139;&amp;#21040;&amp;#33150;&amp;#35759;&amp;#24494;&amp;#21338;"&gt;&lt;/a&gt;  &lt;a href="javascript:void(0);" title="&amp;#20998;&amp;#20139;&amp;#21040;QQ&amp;#31354;&amp;#38388;"&gt;&lt;/a&gt;  &lt;a href="javascript:var b=document.body;var GR________bookmarklet_domain='http://www.google.com';if(b&amp;&amp;!document.xmlVersion){void(z=document.createElement('script'));void(z.src='http://www.google.com/reader/ui/link-bookmarklet.js');void(b.appendChild(z));}else{}" title="&amp;#20998;&amp;#20139;&amp;#21040;Google Reader"&gt;&lt;/a&gt;  &lt;a href="javascript:void(0);" title="&amp;#20998;&amp;#20139;&amp;#21040;&amp;#20154;&amp;#20154;&amp;#32593;"&gt;&lt;/a&gt;  &lt;a href="javascript:void(0);" title="&amp;#20998;&amp;#20139;&amp;#21040;&amp;#35910;&amp;#29923;"&gt;&lt;/a&gt;  &lt;a href="javascript:void(0);" title="&amp;#20998;&amp;#20139;&amp;#21040;&amp;#40092;&amp;#26524;"&gt;&lt;/a&gt;  &lt;a href="javascript:void(0);" title="&amp;#20998;&amp;#20139;&amp;#21040;&amp;#24320;&amp;#24515;"&gt;&lt;/a&gt;  &lt;a href="javascript:void(0);" title="&amp;#20998;&amp;#20139;&amp;#21040;Follow5"&gt;&lt;/a&gt;  &lt;a href="javascript:void(0);" title="&amp;#20998;&amp;#20139;&amp;#21040;&amp;#21516;&amp;#23398;&amp;#32593;"&gt;&lt;/a&gt;  &lt;a href="javascript:void(0);" title="&amp;#20998;&amp;#20139;&amp;#21040;&amp;#22016;&amp;#21653;"&gt;&lt;/a&gt;  &lt;a href="javascript:void(0);" title="&amp;#20998;&amp;#20139;&amp;#21040;&amp;#39277;&amp;#21542;"&gt;&lt;/a&gt;  &lt;a href="javascript:void(0);" title="&amp;#20998;&amp;#20139;&amp;#21040;&amp;#20570;&amp;#21861;"&gt;&lt;/a&gt;  &lt;a href="javascript:void(0);" title="&amp;#20998;&amp;#20139;&amp;#21040;&amp;#30334;&amp;#24230;&amp;#25910;&amp;#34255;"&gt;&lt;/a&gt;  &lt;a href="javascript:void(0);" title="&amp;#20998;&amp;#20139;&amp;#21040;twitter"&gt;&lt;/a&gt;  &lt;a href="javascript:void(0);" title="&amp;#28155;&amp;#21152;&amp;#21040;&amp;#25910;&amp;#34255;&amp;#22841;"&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>System Design 笔记 读写模型</category>
      <guid isPermaLink="true">https://itindex.net/detail/53302-%E6%A8%A1%E5%9E%8B-%E7%AC%94%E8%AE%B0</guid>
      <pubDate>Mon, 27 Apr 2015 09:45:01 CST</pubDate>
    </item>
    <item>
      <title>如何做用户教育？</title>
      <link>https://itindex.net/detail/54534-%E7%94%A8%E6%88%B7-%E6%95%99%E8%82%B2</link>
      <description>&lt;p&gt;做产品设计的这几年，之前一直以为，用户教育，培养用户认知，只能通过产品设计。&lt;/p&gt;
 &lt;p&gt;1，用已有的经验，认知去击中&lt;/p&gt;
 &lt;p&gt;关于用户教育，我最多，也是最初的思考就是利用用户的已有经验。对于此前已有类似产品的时候，抄袭是一个简单有效（但面上无光）的做法，而对于一个从未出现过的产品，就需利用用户的线下经验（还有潜意识）我有一篇几年前的文章说的就是这点（http://kant.cc/post467.html，突然觉得这篇文章有些价值，明天把它也发出来）。&lt;/p&gt;
 &lt;p&gt;2，交互层面的用户教育&lt;/p&gt;
 &lt;p&gt;我们经常可以看到很多一进app就弹框提示，就覆盖界面给你来一些指引，有的适合有N多指引，这特别2。交互层面，最好的用户教育就是没有教育。平台规范最好是不需要用户解释的，或者看一眼就知道，Android Design一直就有这个问题，一方面别人不用，另一方面用了，也没法看一眼就知道，就记住。不过近版的Material Design相对改善了这些问题。&lt;/p&gt;
 &lt;p&gt;3，用钱砸&lt;/p&gt;
 &lt;p&gt;这是最近深有感触的一点。前段时间和一个投资人朋友聊天，他告诉我，许多时候用户不一定用他（原本应该）最适合的方式去做一件事情，产品在有需要时，可以去迫使他。他举的例子特别形象，为了帮助大家理解，我大致改编一下就是，一个拿到非常多钱的做手套的公司（当然这个条件首先不会存在），告诉你用手套抓饭吃不用筷子吃饭，给你200块。1年以后大家都不习惯用筷子吃饭了。还有一个例子是现在，滴滴打车强行用补贴，养成了我身边许多人即使在没补贴情况下也会先叫车再出门的习惯。&lt;/p&gt;
 &lt;p&gt;4，用量砸&lt;/p&gt;
 &lt;p&gt;除了用钱砸，还有一个粗暴的办法是用量砸。比如一个国民应用，强行你对一件事情或一个操作的认知，让你每天都操作几次，你很快就会像狗一样，我的意思是你很快就会像条件反射那样习惯起来。扫一扫是一个很好的例子。&lt;/p&gt;
 &lt;p&gt;基本上，没有办法逃出这4点了，你还有补充或者什么优秀的例子吗？&lt;/p&gt;
 &lt;p&gt;关注我的公众号，阅读更多文章：  &lt;br /&gt;
  &lt;a href="http://kant.cc/wp-content/uploads/2015/05/&amp;#37049;&amp;#21073;&amp;#27874;Kant&amp;#20108;&amp;#32500;&amp;#30721;.jpg"&gt;   &lt;img alt="&amp;#37049;&amp;#21073;&amp;#27874;Kant&amp;#20108;&amp;#32500;&amp;#30721;" height="258" src="http://kant.cc/wp-content/uploads/2015/05/&amp;#37049;&amp;#21073;&amp;#27874;Kant&amp;#20108;&amp;#32500;&amp;#30721;.jpg" width="258"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>学习笔记 所有文章 产品设计 用户教育</category>
      <guid isPermaLink="true">https://itindex.net/detail/54534-%E7%94%A8%E6%88%B7-%E6%95%99%E8%82%B2</guid>
      <pubDate>Thu, 15 Oct 2015 20:29:48 CST</pubDate>
    </item>
    <item>
      <title>BAT这类大公司的稳定工作与创业公司之间，如何选择？</title>
      <link>https://itindex.net/detail/52891-bat-%E5%A4%A7%E5%85%AC-%E5%B7%A5%E4%BD%9C</link>
      <description>&lt;p&gt;很久没有静下心考虑一个话题了，小飞机邀请，我整体考虑一下。恰好这个问题也是我经常被朋友问到的，特别是作为产品经理，许多入门者或者想要入门的学生朋友，对于BAT这类大公司和创业公司之间的选择，是觉得非常头痛的。实际上这种焦虑思考是值得的，因为对于产品经理这类软性工作来说，初期选择很大程度上决定未来成长速度甚至潜力天花板，技术岗位（程序员、设计师）就不太一样，就哪儿做都没事，出来继续有一技傍身。&lt;/p&gt;
 &lt;p&gt;要说在前面的是，如果你个人对BAT（或者Apple、Google）这类大公司有偏好，或者你对创业天生充满热情，非创业公司不去，那这种感性情绪之下，选择皆看个人，你喜欢怎样就选怎样就可。&lt;/p&gt;
 &lt;p&gt;但对于大多数人来说，对于职业选择（特别是更加重要的职业生涯初期的职业选择），是希望做出非常理性（换句话说非常理智）的选择的。而我认为，在任何场合，理性的选择无非就是考虑成本与收益（需要注意你想要考虑的是短期的成本/收益，还是长期的，当然，对于职业选择，窃以为还是多考虑长期为好）。&lt;/p&gt;
 &lt;p&gt;接下来展开剖析一下BAT这类大公司和创业公司的职业选择，对个人的成本与收益。这道选择的答案我们一个个来看。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;答案A：大公司&lt;/strong&gt;  &lt;br /&gt;
大公司的优点是稳定、流程化、方法论，大公司的缺点是稳定、流程化、方法论。如何理解？其实就是，大公司的业务越来越大，越来越多，作坊式、游击队式的产品研发方法和节奏，在没有强而有力的中心人物和中心思想的控制之下，必然容易出问题（多说一句，所以微软、三星、HTC是我一直觉得危险的大公司，它们不像腾讯有产品和体验的极致追求，像百度有技术先行的不懈研究，像阿里有快人多步的战略眼光，和各自非常厉害的创始人）。所以，大公司在自然地机构进化（类似生物进化）中，自然会衍生出帮助控制节奏、避免过大风险、保持随股价一起稳步微涨的流程和方法论。&lt;/p&gt;
 &lt;p&gt;那这对于个人有何影响？直接说来，选择大公司对个人的优势其实就是：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;由于流程严谨，对个人的专业度会有很大提升，往往B的技术，T的产品，A的运营，在业内有口皆碑&lt;/li&gt;
  &lt;li&gt;由于大公司部门多，小九九多（恶意卖萌！），里面的优秀人才往往练就一副沟通神技，会沟通，情商高是越发“显得大”的公司的越发重要的东西&lt;/li&gt;
  &lt;li&gt;收入稳定，工作安逸，没有生存压力&lt;/li&gt;
  &lt;li&gt;价值观问题如果带来正面影响，那么这是你拼搏的时机了&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;劣势就是：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;流程严谨造成层级深厚，所以对个人职级的发展空间和速度一般较小&lt;/li&gt;
  &lt;li&gt;为了保证业务专业度，岗位会很细分，对个人来说会导致业务熟悉度聚焦单面，缺乏整体理解&lt;/li&gt;
  &lt;li&gt;过度安逸带来的缺乏思考，安于现状，工作变成了应付和流于表面&lt;/li&gt;
  &lt;li&gt;人们把遵守流程看待成了比实现更好的业务目标更重要的东西，乔帮主说的这一点简直.不提了&lt;/li&gt;
  &lt;li&gt;价值观问题如果带来负面影响，不要试图改变企业，趁早走最好&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;  &lt;strong&gt;答案B：创业公司&lt;/strong&gt;  &lt;br /&gt;
看完大公司的基本优劣（只谈对个人职业选择的影响，不谈别的，免得字数过多），我们来看看创业公司的。创业公司的优点是敏捷、执行力强、转身快（大多数大公司因为转身慢死掉了，明明看到了刀子，但是里面的优秀个人躲得掉，整体组织躲不掉），缺点是零散、混乱、失控。创业公司的优点对于新市场、新业务，是极其有用的，越新的东西，越需要敏锐嗅觉和快速动作，但创业公司的缺点也很致命，许多创业公司死在会做产品不会做公司。当然，这个缺点有办法破，一是指导人（投资机构、孵化器），二是强而有力的中心化创始人。&lt;/p&gt;
 &lt;p&gt;对个人来说，优劣势也很明确，优势是：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;综合能力会飞速上涨，产品经理变成了辅助程序员，程序员身兼多职&lt;/li&gt;
  &lt;li&gt;生活技能的加点也跟着狂飙（创业后许多小伙伴会做饭了、会做家务和司务了，会修桌子了）&lt;/li&gt;
  &lt;li&gt;对业务理解非常整体、全面，每个创业公司的人都会知道自己公司面对的高层面问题和当前具体问题（否则就白瞎了自己的选择）&lt;/li&gt;
  &lt;li&gt;手握股权，做事更加用心，多年后往往发现自己的心态都变了，甚至那边股票都可以不要，这个东西更重要&lt;/li&gt;
  &lt;li&gt;巨大的生存和竞争压力，带来个人的紧迫感和抗压能力提升&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;劣势是：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;风险巨大，创业公司失败率很高，即使创始人名头再响也是。当然，创始人是优秀的产品经理，往往成功率有小额加成。产品狗受尽凌辱，终于在创业面前，得到了曙光女神的青睐&lt;/li&gt;
  &lt;li&gt;跟错只会耍嘴皮子的创始人，不是浪费时间，而是严重时间倒退&lt;/li&gt;
  &lt;li&gt;工资肯定要低些的，真正的好公司，也不会给你多少股票&lt;/li&gt;
  &lt;li&gt;对职业的专业度、深度，有时候会变得较差&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;当然，无论是大公司还是小公司，里面的劣势都是可以个人角度再做一些事情去规避和缓解的，优势也都是可以放大的，在于你怎么去做，这里要展开的话是另外一个话题，有空再说。我们先看看下面一番话。&lt;/p&gt;
 &lt;p&gt;看完上面的剖析，你似乎觉得选择哪边都各有优劣，没什么正确的选择？抱歉，有一些聪明人的做法（中间做法），似乎才是真正的金手指选择？&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;答案C：大公司中的类创业特殊团队（某同学抓耳，看起来好像应该选C？）&lt;/strong&gt;  &lt;br /&gt;
牛逼的大公司（为避免软文嫌疑，称某讯）的牛逼领导者（马某腾）总是会看到一些真正翻天覆地的变化，是不能用旧有流程去解构和处理的，而又明确知道大公司对新市场和全新领域的劣势，那怎么办？不只是IT行业，所有行业的最好做法都是成立特殊的独立机构和团队，单独面对新领域，或称公司内创业。当然，有的公司内创业假模假样，其实还是受限一大堆，而有的则真的初期任其驰骋最终马到成功，比如某信。这种选择又规避了公司死掉的风险（大公司内部团队死掉问题不太大），又有更快的学习速度（个人随着新领域一起前进，所以风口猪理论对个人也有效），同时还有金钱。当然，进这类特殊团队可能会比进大公司整体，在各方面会更难一些。多说一句，我毕业考试选的是C。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;答案D：已明确竞争力和优势壁垒的创业公司（某同学挠腮，好像D也对啊？）&lt;/strong&gt;  &lt;br /&gt;
很多创业公司看起来很火，其实只是表面。但也有很多创业公司，要么已经明确成为了大型市场的领头羊，公司估值、团队规模和工资奖金都随着市场空间一起年年季季轮轮膨胀（一般是B轮以后）；要么虽然还小，但方向、钱、团队和创始人都让你觉得妥妥竞争力和优势，绝不会死的（一般是A轮，天使一般还太早.）。这两类创业公司，同样是规避了易死风险，又有快速成长各方面涨经验值的好处，还有较好地职级成长空间。这两类优秀创业公司，前一类风险较小，甚至类似于选A了，但它自然就没多少股票也不那么好进了，后一类相对好进（特非常看潜力/价值观和个人学习速度），但风险一般会大一些。有许多MIT、斯坦福的毕业生不像一般人想的那样选A，他们选的其实往往是D。&lt;/p&gt;
 &lt;p&gt;后记  &lt;br /&gt;
这道选择题可能是一道你事业中的最重要的大题，可不只是影响你上个重本还是二本，好好想清楚哦，你选A还是B，还是C，还是D？&lt;/p&gt;
&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>学习笔记 所有文章 产品经理 创业 职业</category>
      <guid isPermaLink="true">https://itindex.net/detail/52891-bat-%E5%A4%A7%E5%85%AC-%E5%B7%A5%E4%BD%9C</guid>
      <pubDate>Sat, 07 Mar 2015 17:59:21 CST</pubDate>
    </item>
    <item>
      <title>长期通过微博、微信、知乎等平台接收碎片化的知识有什么弊端？</title>
      <link>https://itindex.net/detail/53931-%E5%BE%AE%E5%8D%9A-%E5%BE%AE%E4%BF%A1-%E7%9F%A5%E4%B9%8E</link>
      <description>&lt;p&gt;“碎片化”是移动互联网时代的大势，虽说一方面可以将这样的趋势理解做“合理运用时间”。然而长期接受碎片信息的后果也是有弊端的，即碎片化的信息极其容易被我们遗忘。你以为你得到了很多，但其实你什么都没有得到。希望今天分享的文章对同样碎片化的你们有些用。&lt;/p&gt; &lt;p&gt;分享人：张颖&lt;/p&gt; &lt;p&gt;作   者：Lachel (知乎)&lt;/p&gt; &lt;p&gt;  &lt;br /&gt;&lt;/p&gt; &lt;hr&gt;&lt;/hr&gt; &lt;p&gt;你所接受的一切信息，构成了你的思维方式。&lt;/p&gt; &lt;p&gt;所以，长期接受碎片信息的后果，就是让你的思维变得狭隘，难以进行复杂的思考。&lt;/p&gt; &lt;h1&gt;  &lt;strong&gt;1、碎片信息通常具备这样的特征：&lt;/strong&gt;&lt;/h1&gt; &lt;ul&gt;  &lt;li&gt;   &lt;p&gt;它们往往是一些事实的集合而非逻辑    &lt;br /&gt;&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;它们往往大量简化了推演过程&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;它们往往将多路径简化为单一路径&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;它们往往不够严谨、全面……&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;简而言之，碎片信息为了达到易于习得的目的，通常会显著降低认知成本，最明显的方式就是：将复杂的事物简单化。它们往往只告诉你表面上的东西，却不会告诉你背后的原理，以及它与其他事物之间的联系。&lt;/p&gt; &lt;p&gt;我们所说的「知识」，由两部分组成：一是「事实」（或曰「观念」），二是「联系」。事实就是一个个点，联系则是把点连接起来的线，它们所构成的网络，就是我们的知识结构。&lt;/p&gt; &lt;p&gt;  &lt;strong&gt;「事实」决定了你的知识广度，「联系」决定了你的知识深度。&lt;/strong&gt;如果你了解事物之间的联系，即使你只知道ABC，你也可以根据这三者的内在逻辑，得出DE，甚至F，这个过程就叫做思考。但如果你不了解它们的内在逻辑，即使你知道ABCDE，你也是没办法得出F的——你不知道需要把它们放在一起，更不知道放在一起之后它们能够呈现出怎样的内在逻辑关系。&lt;/p&gt; &lt;p&gt;这就是碎片化信息的弊端。当我们接受碎片信息时，我们实际上是在扩充「事实」，但并没有增加「联系」。  &lt;strong&gt;长此以往，会使我们的知识结构变成一张浮点图：孤零零的知识点漂浮在各个位置，却缺乏一个将它们有序串联起来的网络。&lt;/strong&gt;&lt;/p&gt; &lt;h1&gt;  &lt;strong&gt;2、这样的结果是：&lt;/strong&gt;&lt;/h1&gt; &lt;p&gt;1.碎片化知识通过连续的新鲜内容，不断刺激你的大脑，让你始终处于「啊！又知道了新的东西」的喜悦中，从而难以自拔，这也就是我们难以抑制刷微博、刷朋友圈的缘故，因为我们只需要付出很少，就可以沉浸在「获得了新东西」的刺激里面。&lt;/p&gt; &lt;p&gt;但是，这些获得的信息，因为它们  &lt;strong&gt;缺少跟其他信息的「联系」，因此难以被我们「提取」，而「提取」得越少的内容，会被提取得多的内容挤压在记忆的底部&lt;/strong&gt;——因此，这些碎片化的信息极其容易被我们遗忘。你以为你得到了很多，但其实你什么都没有得到。&lt;/p&gt; &lt;p&gt;2.前文已经说过，我们的知识网络，决定了我们如何思考。那么，长期接受碎片信息，对你的思考能力并没有提升——你的「网络」并没有扩大；甚至是有害的——你已经习惯了用孤立的知识点去看待问题，习惯了一层、两层的思维，难以对事物进行五层、六层乃至更深入的剖析。  &lt;strong&gt;长此以往，你将弱化对于复杂事物的思考能力。&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;这里要注意一点：碎片化信息，其实跟来源没有太大关系。如果你习惯了接受「A是B」、「C是坏的」、「因为A所以B」的简单观念，那么，无论你是在刷微博，还是在读书、看公开课，其实接受的都是碎片化知识。&lt;/p&gt; &lt;p&gt;我之前在一个「聪明人的思考方式是什么」的问题中，提到过：聪明人的思考方式，其实很简单，就是三个字：元认知。同样一个问题，较为聪明的人，会去思考这个问题产生的背景、原因、合理性、必要性、可能性，等等。他们会  &lt;strong&gt;拔高一层去看待这个问题，从而更容易找到一根线条，将它和远处的某个固有的「观念」联系在一起，从而拓展自己的思维网络。&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;所以，如果你有这样的意识，那么其实无论刷微博还是读书，都可以避免碎片化认知。&lt;/p&gt; &lt;p&gt;  &lt;img height="161" src="http://static.oschina.net/uploads/space/2015/0720/021809_MQJ8_568818.gif" title="" width="200"&gt;&lt;/img&gt;&lt;/p&gt; &lt;h1&gt;  &lt;strong&gt;3、具体的方式是：&lt;/strong&gt;&lt;/h1&gt; &lt;p&gt;  &lt;strong&gt;1.先花一点时间，建立自己的知识体系。&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;把你已经知道的东西梳理一遍。如何梳理呢？以你能够说出某个知识点的影响因素，以及它对其他事物的影响为准。顺着这样的知识点捋一遍，这个网络就是你已经构建完成的知识网络。&lt;/p&gt; &lt;p&gt;  &lt;strong&gt;2.找到知识网络的触点。&lt;/strong&gt;亦即自己感兴趣的、但尚未进行探索和了解的知识点。阅读、学习的时候，有意识地去接触这些触点的知识，延展自己的知识网络。&lt;/p&gt; &lt;p&gt;  &lt;strong&gt;3.当接触到一个新的知识点时，先考虑如何将其纳入知识体系。&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;亦即在脑子里回想你的知识网络，思考它可以如何跟你已经知道的东西联系起来。&lt;/p&gt; &lt;p&gt;  &lt;strong&gt;4.如果找到了对应的点，弄通路径。&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;亦即，将这个新的知识点，跟已经知道的某个点之间的路径，查清楚、弄清楚，将它们连接起来，使这个知识点成为你新的「触点」，拓展你的思维网络。&lt;/p&gt; &lt;p&gt;  &lt;strong&gt;5.检验并输出。&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;将这两个点之间的联系讲清楚。最简单的办法，就是通过口述、写文章，去教会别人这个知识。或者，在心里把它讲一遍，看是否能够讲得清晰易懂，没有障碍。只有能够输出的东西，才是真正属于你的东西。&lt;/p&gt; &lt;p&gt;  &lt;strong&gt;6.不符合以上方式的内容，果断舍弃。&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;如果一个东西无法纳入你的认知体系，那说明你现在还不能掌握它，那就果断放弃，因为它对你来说是没有价值的，或者说（记忆的）成本是远高于收益的。&lt;/p&gt; &lt;h1&gt;  &lt;strong&gt;4、再多谈几点&lt;/strong&gt;&lt;/h1&gt; &lt;p&gt;  &lt;strong&gt;1.读书不用追求「读完一本书」，而应该追求「从这本书中获得了什么东西」。&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;一本书的内容不可能100%对你有用，其中肯定有你所不感兴趣的东西，也有你所无法接受的东西，没关系，接受你所能接受的即可。不用务求全部读完。甚至，读一半，放回去，再跳着读别的书，也是很好的方式。读书应该为自己所用，而不是让自己去迁就它。&lt;/p&gt; &lt;p&gt;2.如何处理微博上、知乎上那些有趣的碎片化知识？&lt;/p&gt; &lt;p&gt;个人建议，最好的方式，是将它们作为起点。如果你觉得一个知识很有趣，就  &lt;strong&gt;以它为出发点，去探索它背后的原理、背景、应用，去查资料、GOOGLE，顺藤摸瓜。&lt;/strong&gt;这个知识点本身是没有太大价值的，有价值的是你去探索的过程。你经过探索了解到的东西，才能纳入你的知识体系，成为你思维的一部分。&lt;/p&gt; &lt;p&gt;3.以上种种都需要不菲的时间，但学习本就是一件艰难的事情，所以优秀的人永远是凤毛麟角，所谓  &lt;strong&gt;聪明的人，无非他们把走路、等车、休息等更多的时间花在这上面罢了。&lt;/strong&gt;再说，学习本身，岂非也是一件很有趣的事情？:)&lt;/p&gt; &lt;p&gt;点击“Refer链接”还可浏览作者的另外一篇文章：怎么样才能让学习体系化，效果更好？ - Lachel 的回答。希望对你有用。&lt;/p&gt; &lt;h1&gt;5、Refer：&lt;/h1&gt; &lt;p&gt;[1] 长期通过微博、微信、知乎等平台接收碎片化的知识有什么弊端？&lt;/p&gt; &lt;p&gt;  &lt;a href="http://www.zhihu.com/question/30489442/answer/51507979" rel="nofollow" target="_blank"&gt;http://www.zhihu.com/question/30489442/answer/51507979&lt;/a&gt;  &lt;br /&gt;&lt;/p&gt; &lt;p&gt;[2] 网络把我们变傻了吗？ &lt;/p&gt; &lt;p&gt;  &lt;a href="http://user.qzone.qq.com/463148357/blog/1422463146" rel="nofollow" target="_blank"&gt;http://user.qzone.qq.com/463148357/blog/1422463146&lt;/a&gt;  &lt;br /&gt;&lt;/p&gt; &lt;p&gt;[3] 怎么样才能让学习体系化，效果更好？&lt;/p&gt; &lt;p&gt;  &lt;a href="http://zhi.hu/apJx" rel="nofollow" target="_blank"&gt;http://zhi.hu/apJx&lt;/a&gt;  &lt;br /&gt;&lt;/p&gt; &lt;p&gt;[4] 如何构建自己的笔记系统？&lt;/p&gt; &lt;p&gt;  &lt;a href="http://zhi.hu/5xsA" rel="nofollow" target="_blank"&gt;http://zhi.hu/5xsA&lt;/a&gt;  &lt;br /&gt;&lt;/p&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>工作笔记</category>
      <guid isPermaLink="true">https://itindex.net/detail/53931-%E5%BE%AE%E5%8D%9A-%E5%BE%AE%E4%BF%A1-%E7%9F%A5%E4%B9%8E</guid>
      <pubDate>Mon, 20 Jul 2015 02:42:31 CST</pubDate>
    </item>
    <item>
      <title>手机App仍不会取代浏览器</title>
      <link>https://itindex.net/detail/53252-%E6%89%8B%E6%9C%BA-app-%E5%8F%96%E4%BB%A3</link>
      <description>&lt;p&gt;我这几年一直在思考“手机App会不会完全取代手机浏览器，后者是否会逐渐消亡”，观点也几度变化，在当前时间点（2015年4月），我的观点是，  &lt;strong&gt;移动端浏览器在暂时H5的体验仍旧无法达到原生效果的此时，固然在重度、用户重感知的需求上会让步于App，但在可以预见的未来来看，仍旧始终会是一个大型入口，不会被完全取代。&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;早几年，苹果还未搭建起那么吸引人的App大环境，浏览器非常常用，因为人们的手机端需求早于厂商们的App出现，人们不得不在手机上浏览拙劣的未经适配优化的电脑网页，还备受网速、流量的困扰。（我是在描述当时高中/大学的自己）&lt;/p&gt;
 &lt;p&gt;而现在，移动端浏览器发展到今天，各家宣扬的点已经从最初的“省流量”（UC浏览器就是靠此起家）、“速度快”变为了“设计轻”、“嫁接读书/视频内容”、“应用大全”了。早几年的激烈厮杀已经让这块市场基本只剩下了几家巨头产品，比如我个人换机后会装的UC和QQ浏览器（前者感觉比较顺畅，我一直没有弄清楚是动效原因还是真有技术区别，后者是因为是东家的产品），搜狗浏览器、Opera、Chrome（我最常用的其实是这个..）都是比较小众的了。&lt;/p&gt;
 &lt;p&gt;可能许多同学和我一样，并不会在移动浏览器上使用它的应用大全（Web App）啥的，但即使这样，移动端浏览器仍旧会是一个大型入口。  &lt;strong&gt;因为，对于长尾需求、H5/App体验差别不大的需求、搜索等需求形态来说，仍旧是浏览器比App更适合。&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;一个个看。&lt;/p&gt;
 &lt;p&gt;1、搜索  &lt;br /&gt;
搜索对我来说，是一个要用时必须要能马上做到，但频次又不那么多的需求。这类需求很适合在浏览器上来做，因为每次用户换机后，可能不会马上遇到搜索的需求，但总会隐隐感觉需要安装一个App，这就是因为潜意识需要有一个东西可以马上打开www.baidu.com来搜索。这里想到一个事情，UC浏览器团队可能也看出来了未来搜索会是移动端浏览器的很大需求原因，因此自己早早推了神马搜索（当时说实话我没看明白，现在发现当时的决策者的确是前瞻性强）。&lt;/p&gt;
 &lt;p&gt;2、长尾需求  &lt;br /&gt;
长尾需求的典型特征是不值得、懒得安装/不记得要安装这个APP，但是又偶尔出现需求，这时通常就用百度搜索，然后网页解决了，这时也不得不依赖移动浏览器了。实际上，手机百度App目前做到App前5，原因就是人们的搜索需求和长尾需求加起来很多，又实际都是通过浏览器来作为产品形态承载，手机百度就自己做了一个浏览器（手机百度App实质上就是一个不用输入URL的浏览器，实际上是UC和QQ浏览器的重要竞争对手）。&lt;/p&gt;
 &lt;p&gt;3、缺乏App而App没用/做得太烂的情况  &lt;br /&gt;
我们知道，某些网站是没有App的，就不得不用浏览器。比如论坛，虎扑，猫扑等一些网站，还有一些常用但特殊的站点，譬如某榴。或者是App太烂了，和网站没区别，比如贴吧（贴吧稍微做好点，都没same啥机会）。&lt;/p&gt;
 &lt;p&gt;4、App和网页的体验差距不大的需求类型  &lt;br /&gt;
在体验上，并不需要特别的动效体验的需求类型，或者说白了，就是在原生APP上和在H5页上拉不开体验差距的需求类型，也始终是更适合浏览器。典型的例子就是纯粹的阅读，包括阅读小说、看笑话等。如果你只阅读不笔记什么的，浏览器完全够用了，如果你看糗百不会发小纸条上面的，网页版糗百也完全够用了。特别是对基础用户，上面现象更明显，比如我看书，会记笔记，会加色Mark，就得用QQ阅读，而我爸爸，就始终只用浏览器看小说，我跟他说QQ阅读体验更好，翻书效果更舒服，他说哦哦，然后下次回家他还是在用浏览器（我分析根本原因是他觉得没啥区别，那个翻书效果他不在乎，所以他懒得换，保持现状）。小说这一点上，我认为它绝对是除搜索外、移动浏览器里面使用率最高的需求，没有之一，甚至超过看新闻。这一点我纯粹靠个人在身边的观察和臆断，但还算比较有信心，有知道的同学可以与我交流看看。&lt;/p&gt;
 &lt;p&gt;说到未来的长远发展方向，我倒不太明了，倒也没深入想过，但觉得，在H5越来越强的未来，说不定Web APP会开始成为新的热门的服务形式（不过国内，微信公众号也在准备这一方面的事情），届时浏览器又可能有新的机遇。不过说实话，我个人对H5体验的未来始终看不明朗，毕竟对这块技术不甚了解，这又是另一个话题了。&lt;/p&gt;
 &lt;p&gt;微信搜索“邹剑波Kant”即可关注我的公众号，扫描二维码可以请我喝杯茶。  &lt;br /&gt;
  &lt;a href="http://kant.cc/wp-content/uploads/2015/04/2312.jpg"&gt;   &lt;img alt="2312" height="635" src="http://kant.cc/wp-content/uploads/2015/04/2312.jpg" width="640"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>学习笔记 所有文章 APP 浏览器</category>
      <guid isPermaLink="true">https://itindex.net/detail/53252-%E6%89%8B%E6%9C%BA-app-%E5%8F%96%E4%BB%A3</guid>
      <pubDate>Mon, 20 Apr 2015 12:27:58 CST</pubDate>
    </item>
    <item>
      <title>如何构建高扩展性网站？</title>
      <link>https://itindex.net/detail/53205-%E6%89%A9%E5%B1%95-%E7%BD%91%E7%AB%99</link>
      <description>&lt;p&gt;本篇通过阅读《高扩展性网站的50条原则》，总结出以下内容。&lt;/p&gt;
 &lt;p&gt;一方面博主没有实际的架构经验，另一方面知识面也不够宽阔，所以只能系统的总结书中的要点，并根据自己的理解做些归纳。&lt;/p&gt;
 &lt;h2&gt;主要内容&lt;/h2&gt;
 &lt;p&gt;本书从多个方面围绕高扩展性提出了50条建议，一个高扩展性的网站会随着业务的发展、用户的增加，自由的扩展架构，从而轻松的应付网站的快速发展。下面看看本书的具体内容：&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="" src="http://ww4.sinaimg.cn/mw690/6941baebgw1er7npm8svqj20jy16ggp6.jpg"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;h2&gt;化简方程&lt;/h2&gt;
 &lt;p&gt;1 不要过度的设计&lt;/p&gt;
 &lt;p&gt;过度的设计相当于给系统增加了复杂度与维护的成本。而这些过度的设计，在正常的使用中，却没有太大的作用。往往是设计者自己认为很重要或者锦上添花的功能，实际用处不大。&lt;/p&gt;
 &lt;p&gt;2 设计时考虑到扩展性&lt;/p&gt;
 &lt;p&gt;在设计时要遵循一下的设计原则：设计时考虑20倍的容量，实现时考虑3倍的容量，部署时考虑1.5的容量。一面项目扩大时，临时扩展造成的困难。&lt;/p&gt;
 &lt;p&gt;3 把方案一简再简&lt;/p&gt;
 &lt;p&gt;应该遵循帕累托法则，20%的设计做了80%的工作，所以80%的时间，都应该放在这20%的设计上。&lt;/p&gt;
 &lt;p&gt;一个产品主要的功能其实都集中在几个点上，把这几个点设计好了，其他的都是些附加的功能而已。所以这核心的业务一定要保证足够的简洁易用。&lt;/p&gt;
 &lt;p&gt;4 减少DNS查询&lt;/p&gt;
 &lt;p&gt;每个不同的域下的文件，加载时都需要查询DNS。比如cnblogs.com与i.cnblogs.com就属于不同的域。那么在查询DNS的时候，就会查询两次。当业务量很大时，就会造成一定的影响。&lt;/p&gt;
 &lt;p&gt;5 尽可能减少对象&lt;/p&gt;
 &lt;p&gt;由于对象在浏览器访问时，需要加载。所以可以考虑减少请求文件的数量（数量与浏览器并发加载数有关），把一些对象尽量的合并。比如图标类的文件，可以合并成一个大的图片。合理的文件数量，会加速浏览器的访问加载。&lt;/p&gt;
 &lt;p&gt;6 使用同一品牌的网络设备&lt;/p&gt;
 &lt;p&gt;由于一个http请求，可能通过很多物理设备。比如负载均衡器，交换机，路由器。所以尽量使用同一品牌的设备，会避免一些意外的情况。&lt;/p&gt;
 &lt;h2&gt;分布工作&lt;/h2&gt;
 &lt;p&gt;  &lt;img alt="" src="http://ww3.sinaimg.cn/mw690/6941baebgw1er7npnbap3j20jt0erwhn.jpg"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;7 X轴，横向复制&lt;/p&gt;
 &lt;p&gt;这种事最简单的服务扩充，通过克隆或者复制实现，比如你的应用放在多个服务器上进行服务。常见的比如集群，负载均衡等等，数据库的读写分离。&lt;/p&gt;
 &lt;p&gt;8 Y轴，拆分不同的东西&lt;/p&gt;
 &lt;p&gt;大型系统中，拆分不同的功能，比如注册、购买、查询、云盘。等等&lt;/p&gt;
 &lt;p&gt;9 Z轴，拆分不同的相似的东西&lt;/p&gt;
 &lt;p&gt;比如按照用户的级别，或者用户的地理位置等等拆分。&lt;/p&gt;
 &lt;h2&gt;横向扩展设计&lt;/h2&gt;
 &lt;p&gt;10 设计横向的扩展方案&lt;/p&gt;
 &lt;p&gt;扩展包括横向、纵向。横向就是通过复制克隆应用，利用小型机集群扩展。纵向就是提高服务器的硬件以及网络设施。&lt;/p&gt;
 &lt;p&gt;通过很多的案例都可以发现，单纯的升级硬件实现的纵向扩展，仅仅能解决一点点现实压力。而通过横向的集群扩展，却能够自由的实现伸缩。&lt;/p&gt;
 &lt;p&gt;11 采用经济型系统&lt;/p&gt;
 &lt;p&gt;与上面的原则类似，采用高价格的服务器，并不能保证日后的良好性能。应该使用普通的小型机集群扩展。&lt;/p&gt;
 &lt;p&gt;12 横向扩展数据中心&lt;/p&gt;
 &lt;p&gt;数据中心有很多的设计方案，比如&lt;/p&gt;
 &lt;p&gt;热冷站配置：使用热站提供服务，当热站崩溃时，使用冷站继续服务。&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="" src="http://ww4.sinaimg.cn/mw690/6941baebgw1er7npnqhurj20gw0aqq3w.jpg"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;推荐使用多个实时站点，成本更低，动态调用。缺点是增加了运维的难度。&lt;/p&gt;
 &lt;p&gt;13 利用云技术进行设计&lt;/p&gt;
 &lt;p&gt;云计算的有点就是虚拟化，可以在业务峰值时，弹性的扩充设备。并且在日常处理用，归还该扩展。&lt;/p&gt;
 &lt;p&gt;缺点是提高了应用于虚拟环境的耦合。后面提到利用物理设备，隔离业务，在虚拟化的云计算中，可能会对业务隔离错误排查造成一定的干扰。&lt;/p&gt;
 &lt;h2&gt;使用正确的工具&lt;/h2&gt;
 &lt;p&gt;14 合理使用数据库&lt;/p&gt;
 &lt;p&gt;目前有许多的数据库版本，比如传统的关系型数据库Oracle、MySQl，还有比较新的非关系型数据库NoSql，比如MongoDB，以及内存数据库FastDB，还有专门针对SSD固态硬盘的Aerospike等等。&lt;/p&gt;
 &lt;p&gt;但是到了选型的时候，还是要一句个人的业务需求来定。看你的数据库要求的是速度，还是安全性等等。&lt;/p&gt;
 &lt;p&gt;15 防火墙，到处都是防火墙&lt;/p&gt;
 &lt;p&gt;防火墙可以对一些无效的访问进行拦截过滤。通常把一些CSS，静态文件，图片，JS等不采用防火墙，而关键的业务涉及到个人信息时采用。合理的设计防火墙，也会对网站的性能产生一定的影响。&lt;/p&gt;
 &lt;p&gt;16 积极的利用日志文件&lt;/p&gt;
 &lt;p&gt;利用各种日志以及工具，实时的监控业务。不仅仅是监控服务器的内存CPU，还应该监控业务上的数据。比如splunk（提供日志的搜集，存储，搜索，图形化展示）。&lt;/p&gt;
 &lt;h2&gt;不要做重复的工作&lt;/h2&gt;
 &lt;p&gt;17 不要立即检查刚做过的工作&lt;/p&gt;
 &lt;p&gt;比如刚刚写如了数据，不要立即读取。虽然有些客户需要保证数据的完整，不能丢失。但是可以通过日志等记录，写完查这种做法，还是不推荐。&lt;/p&gt;
 &lt;p&gt;18 停止重定向&lt;/p&gt;
 &lt;p&gt;重定向会消耗一定的延迟，计算资源。应该尽量避免&lt;/p&gt;
 &lt;p&gt;19 放松时序约束&lt;/p&gt;
 &lt;p&gt;大多数的关系型数据库讲究ACID属性，扩展时就造成一定的困扰。因此某些业务适当的放松时序约束，可以提高网站的性能。&lt;/p&gt;
 &lt;p&gt;比如某站在预定酒店时，用户预定后，会等待酒店的审核。比如某宝，在提款时，进行范围时间的确认。这种就是扩大了时序约束，进而提高网站性能以及事务安全。&lt;/p&gt;
 &lt;h2&gt;积极利用缓存&lt;/h2&gt;
 &lt;p&gt;20 利用CDN&lt;/p&gt;
 &lt;p&gt;可以利用CDN保存客户的数据和内容。大概的过程是，用户在进行网站访问时，转到CDN的服务器，CDN执行DNS查询，把用户请求分摊到不同的服务器。有很多的CDN服务商提供这种服务。&lt;/p&gt;
 &lt;p&gt;21 使用过期头&lt;/p&gt;
 &lt;p&gt;针对不同的对象类型，使用过期头，减少对象请求。常见的HTTP对应属性为:public no-cahe max-age等等&lt;/p&gt;
 &lt;p&gt;22 缓存Ajax调用&lt;/p&gt;
 &lt;p&gt;正确修改Http头Last-Modified Cache-Control Expires等属性。&lt;/p&gt;
 &lt;p&gt;23 利用页面缓存&lt;/p&gt;
 &lt;p&gt;缓存响应之前的冬天请求，降低web服务器的负载。&lt;/p&gt;
 &lt;p&gt;24 利用应用缓存&lt;/p&gt;
 &lt;p&gt;比如针对某些特殊的用户，缓存其请求数据。&lt;/p&gt;
 &lt;p&gt;25 利用对象缓存&lt;/p&gt;
 &lt;p&gt;适用于反复查询使用的数据对象。比如一个购物网站，缓存器热销产品数据。&lt;/p&gt;
 &lt;p&gt;26 把对象缓存放在自己的层上&lt;/p&gt;
 &lt;p&gt;使用单独的缓层，易于扩展和维护。&lt;/p&gt;
 &lt;h2&gt;从错误中吸取教训&lt;/h2&gt;
 &lt;p&gt;27 积极的学习&lt;/p&gt;
 &lt;p&gt;一个公司有学习的氛围，才会衍生出更好的产品。学习的内容一方面包括客户的业务知识，一方面来自技术和运维领域。&lt;/p&gt;
 &lt;p&gt;28 不要依靠QA发现失误&lt;/p&gt;
 &lt;p&gt;雇佣测试或者质量保证人员，最大的目的是为了检测产品的正确性。它能减少成本，提高开发人员的开发速度，因为开发人员不需要时刻关注代码的正确性，可以交给QA来测试。&lt;/p&gt;
 &lt;p&gt;但是QA只负责发现问题，如何避免为题还是得依靠开发人员。&lt;/p&gt;
 &lt;p&gt;29 没有回退的设计是失败的设计&lt;/p&gt;
 &lt;p&gt;这里的回退，指的是产品发布的回退。如果碰上某些版本的BUG，可能需要交付之前可运行的版本，此时没有回退，就无法交付产品了。&lt;/p&gt;
 &lt;p&gt;这里推荐学习持续集成的相关内容。&lt;/p&gt;
 &lt;p&gt;30 讨论失败并从中吸取教训&lt;/p&gt;
 &lt;p&gt;不应该在同一个问题上失败两次，每次失败多进行总结是不可缺少的。&lt;/p&gt;
 &lt;h2&gt;数据库原则&lt;/h2&gt;
 &lt;p&gt;关系型数据库的ACID属性：&lt;/p&gt;
 &lt;p&gt;原子性：一个事务要么全执行，要么都不执行，&lt;/p&gt;
 &lt;p&gt;一致性：事务开始和结束时，所有数据状态要一致，&lt;/p&gt;
 &lt;p&gt;隔离性：事务的表现，是事务对数据库唯一的操作，&lt;/p&gt;
 &lt;p&gt;持久性：事务完成，操作不能更改。&lt;/p&gt;
 &lt;p&gt;31 注意代价高的关系&lt;/p&gt;
 &lt;p&gt;应该在设计阶段完善的设计表的结构，等开发开始时，在增加某些列，可能会花费很高的代价。&lt;/p&gt;
 &lt;p&gt;32 使用正确的数据库锁&lt;/p&gt;
 &lt;p&gt;数据库有很多锁的概念，比如隐式锁、显式锁、行锁、页锁、范围锁、表锁、数据库锁等等。&lt;/p&gt;
 &lt;p&gt;不合理的使用锁，会影响网站的吞吐量。&lt;/p&gt;
 &lt;p&gt;33 不要使用多阶段提交&lt;/p&gt;
 &lt;p&gt;比如两阶段提交：先表决，在提交。这回降低扩展性，因为在其提交事务完成前，是不能作其他操作的。&lt;/p&gt;
 &lt;p&gt;34 不要使用select for update&lt;/p&gt;
 &lt;p&gt;因为FOR UPDATE从句会导致锁定行，降低事务处理的速度。&lt;/p&gt;
 &lt;p&gt;35 不要选择所有的数据&lt;/p&gt;
 &lt;p&gt;比如select * from xxx;&lt;/p&gt;
 &lt;p&gt;这种做法第一是不开与数据的扩展，比如本来有四列数据，业务处理代码直接写死。当增加了一列数据时，就会导致出错；另外就是会查询出不必要的数据。&lt;/p&gt;
 &lt;p&gt;或者inset into xxx values(xxxx);&lt;/p&gt;
 &lt;p&gt;这是当列信息不匹配时，也会出错。&lt;/p&gt;
 &lt;h2&gt;容错设计与故障控制&lt;/h2&gt;
 &lt;p&gt;36 采用隔离故障的”泳道“&lt;/p&gt;
 &lt;p&gt;服务与数据的划分有很多种，比如容器，集群，池，分片，泳道。泳道意味着每个业务有自己的领域，不能跨泳道调用。&lt;/p&gt;
 &lt;p&gt;37 不要信任单点故障&lt;/p&gt;
 &lt;p&gt;有很多系统设计成单点模式，当整个系统只是用该模块时，当出现单点故障，整个系统也就崩溃了。&lt;/p&gt;
 &lt;p&gt;38 避免系统串联&lt;/p&gt;
 &lt;p&gt;比如一个系统有很多的组件组成，每个组件99.9%的安全性，当串联3个组件时，整个系统的可用性就变成了99.7%。&lt;/p&gt;
 &lt;p&gt;39 确保能够启用/禁用功能&lt;/p&gt;
 &lt;p&gt;对于某些共享库，第三方服务，应该提供开启或者关闭的功能。&lt;/p&gt;
 &lt;h2&gt;避免或分发状态&lt;/h2&gt;
 &lt;p&gt;40 努力实现无状态&lt;/p&gt;
 &lt;p&gt;实现状态会限制扩展性，增大成本&lt;/p&gt;
 &lt;p&gt;41 尽可能在浏览器端维护会话&lt;/p&gt;
 &lt;p&gt;一方面降低服务器压力，另一方面任何的请求可以发送给任何的服务器。&lt;/p&gt;
 &lt;p&gt;42 利用分布式缓存存放状态&lt;/p&gt;
 &lt;p&gt;使用独立的缓存层，利于扩展。有很多分布式的缓存方案，比如memcached。&lt;/p&gt;
 &lt;h2&gt;异步通信和消息总线&lt;/h2&gt;
 &lt;p&gt;43 尽可能使用异步通信&lt;/p&gt;
 &lt;p&gt;异步通信，可以确保每个服务和层之间的独立性，这样易于早呢更加系统的扩展性和减小耦合度。&lt;/p&gt;
 &lt;p&gt;44 确保消息总线能够扩展&lt;/p&gt;
 &lt;p&gt;尽量采用Y轴或者Z轴扩展，即按业务需求和功能扩展。因为单纯的复制或者克隆，反而会增加各个消息订阅者的监听数目。按照业务隔离，可以分离业务压力。&lt;/p&gt;
 &lt;p&gt;45 避免让消息总线过度拥挤&lt;/p&gt;
 &lt;p&gt;衡量价值与消息的成本。&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="" src="http://ww1.sinaimg.cn/mw690/6941baebgw1er7npobi6fj20g20cmdha.jpg"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;h2&gt;其他原则&lt;/h2&gt;
 &lt;p&gt;46 慎用第三方解决方案扩展&lt;/p&gt;
 &lt;p&gt;企业如果出现问题，那么寻找第三方能够解决燃眉之急。但是却不是长久之计，因为解决方案的提供商有很多客户，你的危机并不是他们的危机，所以不可能在关键时刻，尽职尽责。因此企业还是应该有一定的掌控力（这个词真是高大上！）。&lt;/p&gt;
 &lt;p&gt;47 清除、归档和成本合理的存储&lt;/p&gt;
 &lt;p&gt;有一些不必要的数据，就应该定期的删除。一些略有价值的数据进行定期的归档直接删除。一些很有价值的数据，应该进行备份以及快速访问。&lt;/p&gt;
 &lt;p&gt;48 删除事务处理中的商业智能&lt;/p&gt;
 &lt;p&gt;应该把产品系统与业务系统分离，提高产品的扩展性。&lt;/p&gt;
 &lt;p&gt;避免业务扩展时，受到系统架构的限制。&lt;/p&gt;
 &lt;p&gt;49 设计能够监控的应用&lt;/p&gt;
 &lt;p&gt;应该设计全局的监控策略，保证回答&lt;/p&gt;
 &lt;p&gt;”发生了 问题了吗？“&lt;/p&gt;
 &lt;p&gt;”哪里发生了问题？“&lt;/p&gt;
 &lt;p&gt;”发生了什么问题？“&lt;/p&gt;
 &lt;p&gt;”会发生问题吗？“&lt;/p&gt;
 &lt;p&gt;”能自动修复吗？“&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="" src="http://ww4.sinaimg.cn/mw690/6941baebgw1er7npoxokuj20hu0csdh3.jpg"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;50 要能胜任&lt;/p&gt;
 &lt;p&gt;应该在每个设计中涉及到最优秀的架构，不能完全依赖第三方的解决方案。&lt;/p&gt;
 &lt;p&gt;一个简单优秀的架构，都是小而精的，如果单纯的依靠开源解决架构，虽然解决了问题，却会导致应用的臃肿。&lt;/p&gt;
 &lt;h2&gt;参考&lt;/h2&gt;
 &lt;p&gt;【1】《高扩展性网站的50条原则》&lt;/p&gt;
 &lt;div&gt;
  &lt;div&gt;
   &lt;h3&gt;相关文章&lt;/h3&gt;
   &lt;ul&gt;
    &lt;li&gt;     &lt;a href="http://blog.jobbole.com/34212/"&gt;可伸缩系统的架构经验&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;     &lt;a href="http://blog.jobbole.com/31817/"&gt;《sed &amp;amp; awk》读书笔记之 awk 篇&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;     &lt;a href="http://blog.jobbole.com/31026/"&gt;《sed &amp;amp; awk》读书笔记之 sed 篇&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;     &lt;a href="http://blog.jobbole.com/47630/"&gt;Reddit月浏览量从百万扩容到十亿的陷阱和教训&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;     &lt;a href="http://blog.jobbole.com/78494/"&gt;『黑客与画家』读书笔记&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;     &lt;a href="http://blog.jobbole.com/24524/"&gt;《用户体验的要素》笔记&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;     &lt;a href="http://blog.jobbole.com/24393/"&gt;有关读书求知的一些想法&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;     &lt;a href="http://blog.jobbole.com/36558/"&gt;编写可读代码的艺术&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;     &lt;a href="http://blog.jobbole.com/78487/"&gt;『暗时间』读书笔记&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;     &lt;a href="http://blog.jobbole.com/49981/"&gt;读《程序员的思维修炼》&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;p&gt;  &lt;a href="http://blog.jobbole.com/86118/"&gt;如何构建高扩展性网站？&lt;/a&gt;，首发于  &lt;a href="http://blog.jobbole.com"&gt;博客 - 伯乐在线&lt;/a&gt;。&lt;/p&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>IT技术 架构 读书笔记</category>
      <guid isPermaLink="true">https://itindex.net/detail/53205-%E6%89%A9%E5%B1%95-%E7%BD%91%E7%AB%99</guid>
      <pubDate>Thu, 16 Apr 2015 19:57:46 CST</pubDate>
    </item>
    <item>
      <title>Android Design的根本问题到底是什么？</title>
      <link>https://itindex.net/detail/52114-android-design-%E9%97%AE%E9%A2%98</link>
      <description>&lt;p&gt;注1：笔者从Android1.5用到Android5.0，一直很喜欢开放的特质，但很愤恨Google早期的设计资源投入和思考得太少。  &lt;br /&gt;
注2：Android Design中有一些非常傻的细节点（iOS/WinPhone早期也有），简直让人失去对它的讨论兴趣，但现在改得差不多了，这里就略过不谈，主要针对现今的Android Design来说。&lt;/p&gt;
 &lt;p&gt;Android Design目前是一个比较差的设计标准（4.0之前属于很差，2.3之前属于垃圾/没有设计/没有思考），在Android Design成为一个较好的设计标准之前，不建议用户量超过1000万的App使用Android Design（国外的不同，具体见下）。&lt;/p&gt;
 &lt;p&gt;知乎/设计社区有一些喜爱和宣扬Android Design的人，说真的，你们主导的App可能比较难做到大的用户量（的同时仍被主流用户喜欢），需要思考一点，设计师们是应该为自己/为标准（形式主义、教旨主义）设计，还是为了好用/产品体验/被主流用户喜欢而设计。&lt;/p&gt;
 &lt;p&gt;给你们的爸爸妈妈，身边不玩机的主流人群用用所谓的标准Android Design设计吧。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;绝大多数Google的东西设计得比较工程师思维、过于理性，对逻辑有思考，得出了逻辑清晰的设计结论（因而容易产生深信逻辑而不顾用户感情的信徒），但对小白（特别是落后国家的小白）和小白的接受/学习能力的思考太少。&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;许多Google的App，我用着是觉得不算太差的（但必须得去掉二维应用导航的抽屉设计、大多数侧栏设计、图标仅露出右边的一半以暗示滑屏还有内容，等等一大堆极差的白痴思路），如Inbox、Gmail，但我给身边的主流不熟悉IT的人用，发现简直在折磨他们。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;可以认为，Android Design根本问题在于设计思路略显超前&lt;/strong&gt;（嗯早期Android系统的问题就是没有设计，恶心程度简直不想举例，如果你跟我一样从Android1.5用到Android5.0，你也会懂）。估计决策者早已知道这个问题，但此时没有必要改思路了（改回原始而更容易接受的设计思路，不知多久的以后还得再改回来，没有必要）。&lt;/p&gt;
 &lt;p&gt;Google的纯粹逻辑思维设计（某些时候为了简洁而简洁，某些时候只看逻辑不看体验和认知）是工程师式的思维。从逻辑和道理上说都是对的，比如常用APP放桌面，不常用放抽屉，看似很有道理，但是小白理解不了（他们只在一个地方找APP，就是他们第一眼看到的桌面），或许在几十年之后，智能手机对每一个人类，就像遇到奶嘴就自然地会去吮吸时，Android Design的思路才是对的。找APP这个具体设计点，可以做一个“关于储物”的类比。人类初始阶段的储物，是在屋子内随处乱放的，在人类对空间和物品储存思路足够熟悉、物品足够多足够复杂后，才有储物柜、分门别类的抽屉的做法。  &lt;strong&gt;谷歌的设计就是略过了前面阶段，直接到了后面（从科学/工程师/纯理性/逻辑的角度来说，后面的做法当然是更对更先进的，但用户就是暂时接受不了）。&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;前面提到的国外的不同，其实就在于国外的发达国家的人们更利于尝试、更喜欢尝鲜，学习/接受速度更快。  &lt;strong&gt;给第三世界的国家像中国市场一样足够大的市场、激烈的竞争环境、较低水平的国民教育程度和理解能力（和公司/企业无关），这些国家的互联网/移动互联网产品的设计，也一定会趋于以触摸、直观、逻辑层级浅、逻辑维度少的设计风格和标准（也就是iOS设计标准之于Android设计标准）。&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;从这个角度来说，其实iPhone的设计思路也是在往Android Design的思路上靠（大量的教育用户的细节，变为了更多是简洁和注重内容展现。例子来说，给无前置教育的小孩子用iOS6比用iOS7，前者他更会用），但iPhone有过成熟的设计标准和持续几代的风格和设计细节延续。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;或许过几年/几十年之后，人类对手机交互天然就会包括“滑动”这个操作（现在人类对手机交互的无前置认知只有触摸/点击，这是从几千年的实物操作中总结来的基因和经验）。到那时，大量采用滑动操作的设计才能被无前置教育的人快速接受。&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;而在此之前，更保守、直观、逻辑层级更浅、逻辑维度更少的iOS设计标准，始终要比逻辑正确、思维超前、追求简洁大于易理解、追求效率快大于好接受的Android设计标准，要好得多（好的标准是更受主流用户的接受、使用和喜欢）。&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;另参见：  &lt;br /&gt;
  &lt;a href="http://www.zhihu.com/question/23226203/answer/30782584"&gt;有综合实力超过了 iPhone 的 Android 手机吗？ – 邹剑波Kant 的回答&lt;/a&gt;&lt;/p&gt;
&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>学习笔记 所有文章 Android 产品设计</category>
      <guid isPermaLink="true">https://itindex.net/detail/52114-android-design-%E9%97%AE%E9%A2%98</guid>
      <pubDate>Tue, 09 Dec 2014 21:57:36 CST</pubDate>
    </item>
    <item>
      <title>《大型网站技术架构》 笔记 － 架构篇</title>
      <link>https://itindex.net/detail/50290-%E7%BD%91%E7%AB%99-%E6%8A%80%E6%9C%AF-%E6%9E%B6%E6%9E%84</link>
      <description>&lt;h1&gt;第四章 瞬时响应：网站的高性能架构&lt;/h1&gt;
 &lt;h2&gt;4.1 网站性能测试&lt;/h2&gt;
 &lt;p&gt;性能测试是性能优化的前提和基础，也是性能优化结果的检查和度量标准。&lt;/p&gt;
 &lt;p&gt;性能测试的指标有：响应时间、并发数、吞吐量、性能计数器。&lt;/p&gt;
 &lt;p&gt;网站性能优化的目的，除了改善用户体验的响应时间，还要尽量提升系统吞吐量，最大限度利用服务器资源。&lt;/p&gt;
 &lt;h2&gt;4.2 Web 前端性能优化&lt;/h2&gt;
 &lt;p&gt;主要手段有优化浏览器访问、使用反向代理、CDN加速等。&lt;/p&gt;
 &lt;p&gt;&lt;/p&gt;
 &lt;h3&gt;4.2.1 浏览器访问优化&lt;/h3&gt;
 &lt;ul&gt;
  &lt;li&gt;减少http请求：合并、压缩CSS、JS，合并图片，   &lt;em&gt;使用Ajax局部刷新页面&lt;/em&gt;。&lt;/li&gt;
  &lt;li&gt;
   &lt;p&gt;使用浏览器缓存：&lt;/p&gt;
   &lt;blockquote&gt;
    &lt;ul&gt;
     &lt;li&gt;Expires：告诉缓存器：相关副本在多长时间内是新鲜的。过了这个时间，缓存器就会向源服务器发送请求，检查文档是否被修改。&lt;/li&gt;
     &lt;li&gt;Cache-Control：      &lt;br /&gt;
  &amp;gt;   *   max-age=[秒] — 执行缓存被认为是最新的最长时间。这个参数是基于请求时间的相对时间间隔，而不是绝对过期时间，[秒]是一个数字，单位是秒：从请求时间 开始到过期时间之间的秒数。      &lt;br /&gt;
  &amp;gt;   *   s-maxage=[秒] — 类似于max-age属性，除了他应用于共享（如：代理服务器）缓存      &lt;br /&gt;
  &amp;gt;   *   public — 标记认证内容也可以被缓存，一般来说： 经过HTTP认证才能访问的内容，输出是自动不可以缓存的；      &lt;br /&gt;
  &amp;gt;   *   no-cache — 强制每次请求直接发送给源服务器，而不经过本地缓存版本的校验。这对于需要确认认证应用很有用（可以和public结合使用），或者严格要求使用最新数据 的应用（不惜牺牲使用缓存的所有好处）；      &lt;br /&gt;
  &amp;gt;   *   no-store — 强制缓存在任何情况下都不要保留任何副本      &lt;br /&gt;
  &amp;gt;   *   must-revalidate — 告诉缓存必须遵循所有你给予副本的新鲜度的，HTTP允许缓存在某些特定情况下返回过期数据，指定了这个属性，你高速缓存，你希望严格的遵循你的规则。      &lt;br /&gt;
  &amp;gt;   *   proxy-revalidate — 和 must-revalidate类似，除了他只对缓存代理服务器起作用。&lt;/li&gt;
     &lt;li&gt;Last-Modified/If-Modified-Since：第一次请求资源时，服务器在响应头里设置 Last-Modified 为资源的最后修改时间，浏览器第二次请求资源时，在请求头里带上上次响应的 Last-Modified 值，服务器检测到资源自此值后没有修改，则仅返回 304 响应头。&lt;/li&gt;
     &lt;li&gt;ETag/If-None-Match：服务器发送你所请求的数据的同时，发送数据的某种 hash (在 ETag 头信息中给出)。hash 的确定完全取决于服务器。当第二次请求相同的数据时，你需要在 If-None-Match 头信息中包含 ETag hash，如果数据没有改变，服务器将仅返回 304 状态代码。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
  &lt;li&gt;
   &lt;p&gt;服务端启用GZip压缩&lt;/p&gt;
&lt;/li&gt;
  &lt;li&gt;CSS 放在页面最上面，JS放在页面最下面：浏览器在下载完全部CSS之后才开始对整个页面进行渲染；在加载JS后立即执行，可能会阻塞页面，造成页面显示缓慢。&lt;/li&gt;
  &lt;li&gt;减少Cookie传输：Cookie包含在每次请求和响应中，太大的Cookie会影响数据传输；对于静态资源，发送Cookie没有意义，可以对静态资源使用独立域名。&lt;/li&gt;
  &lt;li&gt;对不同的静态资源使用独立域名：浏览器对同一个域同时访问的连接数是有限制的，增加不同的域可以加快资源加载。&lt;/li&gt;
&lt;/ul&gt;
 &lt;h2&gt;4.3  应用服务器性能优化&lt;/h2&gt;
 &lt;p&gt;主要手段有缓存、集群、异步等。&lt;/p&gt;
 &lt;p&gt;网站性能优化第一定律：优先考虑使用缓存优化性能。&lt;/p&gt;
 &lt;p&gt;缓存主要用来存放那些读写比很高、很少变化的数据。&lt;/p&gt;
 &lt;p&gt;任何可以晚点做的事情都应该晚点再做。&lt;/p&gt;
 &lt;p&gt;代码优化：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;多线程：   &lt;code&gt;启动线程数＝[任务执行时间/(任务执行时间－IO等待时间)]*CPU内核数&lt;/code&gt;。解决线程安全的主要手段：将对象设计为无状态对象、使用局部变量、并发访问资源时使用锁。&lt;/li&gt;
  &lt;li&gt;资源复用&lt;/li&gt;
  &lt;li&gt;恰当的数据结构&lt;/li&gt;
  &lt;li&gt;关注垃圾回收：&lt;/li&gt;
&lt;/ul&gt;
 &lt;h2&gt;4.5  小结&lt;/h2&gt;
 &lt;p&gt;网站性能优化的主要工作是改善高并发下情况下的网站响应速度。&lt;/p&gt;
 &lt;p&gt;网站性能对最终用户而言是一种主观感受，性能优化的最终目的就是改善用户的体验，使他们感觉网站很快。离开这个目的，追求技术上的所谓高性能，是舍本逐末，没有多大意义。而用户体验的快或慢，可以通过技术手段改善，也可以通过优化交互体验改善。&lt;/p&gt;
 &lt;h1&gt;第五章 万无一失：网站的高可用架构&lt;/h1&gt;
 &lt;h2&gt;5.2 高可用的网站架构&lt;/h2&gt;
 &lt;p&gt;完整的高可用架构设计的主要目的是保证服务器硬件故障时服务依然可用、数据依然保存并能够被访问。&lt;/p&gt;
 &lt;p&gt;实现上述高可用架构的主要手段是数据和服务的冗余备份以及失效转移。&lt;/p&gt;
 &lt;p&gt;位于应用层和服务层的服务器为了应对高并发的访问请求，会通过负载均衡设备将一组服务器组成一个集群共同对外提供服务。&lt;/p&gt;
 &lt;p&gt;位于数据层的服务器需要在数据写入时进行数据同步复制，将数据写入多台服务器上，实现数据冗余备份。&lt;/p&gt;
 &lt;h2&gt;5.3 高可用的应用&lt;/h2&gt;
 &lt;p&gt;通过负载均衡进行无状态服务的失效转移。&lt;/p&gt;
 &lt;h3&gt;Session 管理&lt;/h3&gt;
 &lt;ul&gt;
  &lt;li&gt;Session 复制：简单，占用服务器内存、带宽资源。&lt;/li&gt;
  &lt;li&gt;Session 绑定：将同一IP或Cookie信息转发到特定的服务器，不满足高可用。&lt;/li&gt;
  &lt;li&gt;利用Cookie 记录Session：简单可靠性高，支持应用服务器线性伸缩；受cookie大小限制，每次请求要传输cookie，影响性能，如果用户关闭cookie，访问会不正常。&lt;/li&gt;
  &lt;li&gt;Session 服务器：这种解决方案将应用服务器的状态分离，分为无状态的应用服务器和有状态的 session 服务器；应用服务器每次读写 sission，都访问 session 服务器。&lt;/li&gt;
&lt;/ul&gt;
 &lt;h2&gt;5.4 高可用的服务&lt;/h2&gt;
 &lt;p&gt;也是通过负载均衡和失效转移机制失效。&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;分级管理：对服务进行分级管理，确保优先级高的服务；在部署上进行隔离，避免故障的连锁反应。&lt;/li&gt;
  &lt;li&gt;超时设置：可避免请求长时间不能得到响应。&lt;/li&gt;
  &lt;li&gt;异步调用：应用对服务的调用通过消息队列等异步方式完成，避免一个服务失败导致整个应用请求失败的情况。&lt;/li&gt;
  &lt;li&gt;
   &lt;p&gt;服务降级：有两种手段：拒绝服务和关闭关闭服务。&lt;/p&gt;
   &lt;blockquote&gt;
    &lt;ul&gt;
     &lt;li&gt;拒绝服务：拒绝低优先级应用的调用，减少服务调用的并发数，确保核心应用正常使用；或者随机拒绝部分请求调用，节约资源，让一部分请求成功，避免要死大家一起死的惨剧。&lt;/li&gt;
     &lt;li&gt;关闭服务：关闭部分不重要的服务，或者服务内部关闭部分不重要的功能，以节约系统开销，为重要的服务和功能让出资源。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
  &lt;li&gt;
   &lt;p&gt;幂等性设计：服务层保证重复调用和调用一次产生的结果相同，即服务具有幂等性。服务重复调用是无法避免的。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
 &lt;h2&gt;5.5 高可用的数据&lt;/h2&gt;
 &lt;p&gt;保证数据高可用的手段主要是数据备份和失效转移机制。&lt;/p&gt;
 &lt;h3&gt;CAP 原理&lt;/h3&gt;
 &lt;p&gt;CAP 原理认为一个提供数据服务的存储系统无法同时满足数据一致性（Consistency）、数据可用性（Availability）、分区耐受性（Partition Tolerence，系统具有跨网络分区的伸缩性）。&lt;/p&gt;
 &lt;p&gt;在大型网站中，通常会选择强化分布式系统的可用性（A）和伸缩性（P），在某种程度上放弃一致性（C）。&lt;/p&gt;
 &lt;p&gt;数据一致性又分为：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;数据强一致性：各个副本的数据在物理存储中总是一致的。&lt;/li&gt;
  &lt;li&gt;数据用户一致性：各个副本的数据可能是不一致的，终端用户访问时，通过纠错和校验机制，可以确定一个一致的且正确的数据返回给用户。&lt;/li&gt;
  &lt;li&gt;数据最终一致：物理存储的数据可能是不一致的，终端用户访问到的结果可能也是不一致的，但系统经过一段时间的自我修复和修正，数据最终会达到一致。&lt;/li&gt;
&lt;/ul&gt;
 &lt;h3&gt;数据备份&lt;/h3&gt;
 &lt;p&gt;数据备份分为冷备份和热备份，热备份又分为异步热备份和同步热备份。&lt;/p&gt;
 &lt;p&gt;在异步写入方式下，存储服务器分为主存储服务器（Master）和从存储服务器（Slave），应用程序通常只连接 Master，数据写入时，由 Master 的写代理操作模块将数据写入本机存储系统后立即返回写操作成功响应，然后通过异步线程将写操作数据同步到 Slave。&lt;/p&gt;
 &lt;p&gt;同步方式是指多份数据副本的写入操作同步完成，即应用程序收到数据服务系统的写成功响应时，多份数据的都已经写操作成功。&lt;/p&gt;
 &lt;h3&gt;失效转移&lt;/h3&gt;
 &lt;p&gt;失效转移操作由三个部分组成：失效确认、访问转移、数据恢复。&lt;/p&gt;
 &lt;p&gt;失效确认主要通过心跳检测和应用程序访问失败报告。&lt;/p&gt;
 &lt;h2&gt;5.6 高可用网站的软件质量保证&lt;/h2&gt;
 &lt;ul&gt;
  &lt;li&gt;网站发布&lt;/li&gt;
  &lt;li&gt;自动化测试&lt;/li&gt;
  &lt;li&gt;预发布验证&lt;/li&gt;
  &lt;li&gt;代码控制&lt;/li&gt;
  &lt;li&gt;自动化发布&lt;/li&gt;
  &lt;li&gt;灰度发布&lt;/li&gt;
&lt;/ul&gt;
 &lt;h2&gt;5.7 网站运行监控&lt;/h2&gt;
 &lt;p&gt;不允许没有监控的系统上线。&lt;/p&gt;
 &lt;h3&gt;监控数据采集&lt;/h3&gt;
 &lt;p&gt;用户行为日志：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;服务器端日志&lt;/li&gt;
  &lt;li&gt;客户端浏览器日志&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;服务器性能监控。&lt;/p&gt;
 &lt;p&gt;运行数据报告。&lt;/p&gt;
 &lt;h3&gt;监控管理&lt;/h3&gt;
 &lt;p&gt;系统报警、失效转移、自动优雅降级。&lt;/p&gt;
 &lt;h1&gt;第六章 永无止境：网站的伸缩性架构&lt;/h1&gt;
 &lt;h2&gt;6.1 网站架构的伸缩性设计&lt;/h2&gt;
 &lt;p&gt;网站的伸缩性架构可分成两类：一类是根据功能进行物理分离实现伸缩，一类是单一功能通过集群实现伸缩。&lt;/p&gt;
 &lt;p&gt;当一头牛拉不动车的时候，不要去找一头更强壮的牛，而是用两头牛去拉车。&lt;/p&gt;
 &lt;h4&gt;负载均衡的基础技术&lt;/h4&gt;
 &lt;ul&gt;
  &lt;li&gt;HTTP 重定向负载均衡：采用 HTTP 重定向服务器，根据用户 HTTP 请求计算一台真实的 web 服务器地址，将该服务器地址写入 HTTP 重定向响应中返回给用户浏览器。需要两次访问才能完成一次请求，重定向服务器自身的处理能力有可能称为瓶颈。&lt;/li&gt;
  &lt;li&gt;DNS 域名解析负载均衡：在DNS 服务器中配置多个 A 记录，每次域名解析请求都会根据负载均衡算法计算一个不同的 IP 地址返回，这样 A 记录中配置的多个服务器就构成一个集群，并可以实现负载均衡。DNS 的解析有延迟。&lt;/li&gt;
  &lt;li&gt;反向代理负载均衡：反向代理服务器需要配置双网卡和内部外部两套 IP 地址，工作在 HTTP 协议层，也叫应用层负载均衡。&lt;/li&gt;
  &lt;li&gt;IP 层负载均衡：在网络层通过修改请求目标的地址进行负责均衡。&lt;/li&gt;
  &lt;li&gt;数据链路层负载均衡：在数据链路层修改 mac 地址进行负载均衡。在分发过程中不修改 IP 地址，只修改目的 mac 地址，通过配置真实物理服务器集群所有机器虚拟 IP 和负载均衡服务器 IP 地址一致，从而达到不修改数据包的源地址和目的地址就可以进行数据分发的目的。也称作直接路由（DR）。&lt;/li&gt;
&lt;/ul&gt;
 &lt;h4&gt;负载均衡算法&lt;/h4&gt;
 &lt;ul&gt;
  &lt;li&gt;轮询（Round Robin，RR）：所有请求被依次分发到每台应用服务器上。&lt;/li&gt;
  &lt;li&gt;加权轮询（Weighted Round Robin，WRR）：在轮询的基础上，按配置的权重将请求分发到每台服务器上。&lt;/li&gt;
  &lt;li&gt;随机（Random）：请求被随机分发到各个应用服务器上。&lt;/li&gt;
  &lt;li&gt;最少连接（Least Connection）：记录每个应用服务器正在处理的连接数，将新到的请求分发到最少连接的服务器上。&lt;/li&gt;
  &lt;li&gt;源地址算列（Source Hashing）：根据请求来源的 IP 地址进行分发请求，同一个 IP 总是分发到同一台服务器上。&lt;/li&gt;
&lt;/ul&gt;
 &lt;h1&gt;第七章 随需应变：网站的可扩展性&lt;/h1&gt;
 &lt;ul&gt;
  &lt;li&gt;扩展性（Extensibility）：指对现有系统影响最小的情况下，系统功能可持续扩展或提升的能力。表现在基础设施稳定不需要经常变更，应用之间少依赖和耦合，对需求变更可以敏捷响应。&lt;/li&gt;
  &lt;li&gt;伸缩性（Scalability）：指系统能够通过增加（减少）自身资源规模的方式增强（减少）自己计算处理事务的能力。这种增减是成比例的，就被称作线性伸缩。&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;设计网站可扩展架构的核心思想是模块化，并在此基础之上，降低模块间的耦合性，提供模块的复用性。&lt;/p&gt;
 &lt;p&gt;分层和分割是模块化设计的重要手段，模块之间以消息传递和依赖调用的方式聚合成一个完整的系统。&lt;/p&gt;
 &lt;p&gt;模块分布式部署以后具体的聚合方式主要有分布式消息队列和分布式服务。&lt;/p&gt;
 &lt;p&gt;大型网站分布式服务的需求与特点：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;服务的注册与发现&lt;/li&gt;
  &lt;li&gt;服务调用&lt;/li&gt;
  &lt;li&gt;负载均衡&lt;/li&gt;
  &lt;li&gt;失效转移&lt;/li&gt;
  &lt;li&gt;高效的远程通信&lt;/li&gt;
  &lt;li&gt;整合异构系统&lt;/li&gt;
  &lt;li&gt;对应用最少入侵&lt;/li&gt;
  &lt;li&gt;版本管理&lt;/li&gt;
  &lt;li&gt;实时监控&lt;/li&gt;
&lt;/ul&gt;
 &lt;h1&gt;第八章 固若金汤：网站的安全架构&lt;/h1&gt;
 &lt;div&gt;
&lt;/div&gt;
&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>读书笔记 网站架构</category>
      <guid isPermaLink="true">https://itindex.net/detail/50290-%E7%BD%91%E7%AB%99-%E6%8A%80%E6%9C%AF-%E6%9E%B6%E6%9E%84</guid>
      <pubDate>Sun, 06 Jul 2014 20:56:12 CST</pubDate>
    </item>
    <item>
      <title>量子基金创始人吉姆·罗杰斯给女儿的18条建议</title>
      <link>https://itindex.net/detail/48117-%E9%87%8F%E5%AD%90%E5%9F%BA%E9%87%91-%E5%88%9B%E5%A7%8B%E4%BA%BA-%E7%BD%97%E6%9D%B0%E6%96%AF</link>
      <description>&lt;p&gt;​本文翻译自吉姆·罗杰斯的《给女儿的礼物》（A Gift to My Children）。吉姆·罗杰斯是华尔街著名的投资家、环球旅行者，他与索罗斯共同创办了量子基金。与别的投资家不同，他投资之前，除了阅读报表、书报之外，还喜欢实地考察，用脚丈量大地。他曾两次驾车周游世界100多个国家，获得了大量的第一手材料。他今年72岁，有两个女儿，大女儿叫Happy，今年11岁，小女儿叫Bee，今年6岁，不但能歌善舞，而且都能说一口流利的汉语。这本《给女儿的礼物》，就是写给两位女儿的信，出版于2009年，诚恳真挚，智慧满溢。&lt;/p&gt;
 &lt;p&gt;1、永远买高质量的商品，它们不但耐用，而且残存价值高。&lt;/p&gt;
 &lt;p&gt;2、去采购食品之前，记得要吃饱。如果你饿着肚子，将会买回一大堆超出所需的食物。&lt;/p&gt;
 &lt;p&gt;3、任何贴着“必看”、“必读”、“必须试试”标签的东西，都要避开，尤其是流行的，更要退避三舍。保持良好的教养，无论身处何方，无论对面是谁。这可以把你与他人永久区分开来。在任何社会，都要入乡问俗、入乡随俗。&lt;/p&gt;
 &lt;p&gt;4、无论在哪儿都要警惕从政的人，他们也就是在校时了了，大未必佳。&lt;/p&gt;
 &lt;p&gt;5、永远不要问别人赚多少钱以及某样东西值多少钱。不要告诉别人你的东西多少钱买的。不要跟人谈论你赚多少钱以及有多少身家。这是咱们家族根深蒂固的传统，从我的爷爷那辈开始，大家就遵循，因为谈论这些事不但扎眼，而且缺乏教养，至少对我们家而言是这样。证明自己要靠行为，而不是谈钱。如今很多人喜欢谈钱，但我不希望你们这样。&lt;/p&gt;
 &lt;p&gt;6、如果你们借钱，一定要提前还，至少要按时还。好的信用至关重要，坏的信用记录会困扰你许多年。&lt;/p&gt;
 &lt;p&gt;7、等你们长大了，会跟男孩们打交道。我希望永远给你们建议和警告。与他们交往的基本原则是：记住他们对你们的需求远远大于你们对他们的需求。当他们狂热追你们的时候，他们会许下千万条诺言。实话告诉你们，这种漂亮话我能说得比他们好。直接忽略他们，对自己诚实。当听到荒谬的许诺、奉承、夸奖时，运用你们的常识。不要追随男孩们转学、迁徙、换工作。让他们来追随你。&lt;/p&gt;
 &lt;p&gt;8、等你们长大了，要知道你们单独去酒吧几乎没什么好处。吧台的少爷们知道的、经历的比你们多得多，他们会从你们这里讨便宜。&lt;/p&gt;
 &lt;p&gt;9、要警惕：许多看上去跟你爸爸或爷爷一样年纪的人，并不会把你们当成他的女儿或孙女。&lt;/p&gt;
 &lt;p&gt;10、在你们28岁之前不要结婚，只有到了这个年纪，你们才会对自身、对世界有所了解。&lt;/p&gt;
 &lt;p&gt;11、非常重要的一点：要分清好工作与生活的边界。下班后不要跟同事们去吃吃喝喝，你会发现，当老板的从来不会这么干，所以他们才是老板。永远没必要跟老板去喝酒，尤其是两人单独。永远不要在商务午餐时饮酒。最后，还有很重要的一点，避免发生办公室恋情。这件事总是以个人和职业的悲剧而结束。&lt;/p&gt;
 &lt;p&gt;12、在开长途车或在公共场合露面之前，记得要先去洗手间。&lt;/p&gt;
 &lt;p&gt;13、学会打字和缝纫，我不会，故而常后悔。&lt;/p&gt;
 &lt;p&gt;14、学会心算，虽然到处都有计算器，但心算会让你对数字更敏感，从而发现别人视而不见的机会。心算能让你们受益终生。&lt;/p&gt;
 &lt;p&gt;15、照顾好自己，一个人如果身体不好、休息不好，则很难成功。你们知道妈妈经常给你们擦防晒霜，她是对的。&lt;/p&gt;
 &lt;p&gt;16、当面临压力和混乱时，记得要冷静。这能让你做出清醒决定，也能让别人注意到你们的冷静沉着。我经常头脑发热，现在常常后悔。&lt;/p&gt;
 &lt;p&gt;17、与人有约，一定要早到。你这样做，不但能让自己保持高效，还能给人以好印象，因为大多数人都迟到，还有人每次都迟到。&lt;/p&gt;
 &lt;p&gt;18、一旦你对自己有了清醒的认识和理解，记住你是谁，并且保持住。我有时还会迷失，感情用事，或者做自己不擅长的事。当回首往昔，我真想踢自己，让自己对自己诚实。例如，我投资的时候，有时会跟着感觉走。我经常后悔，自己没有坚守住自己最擅长的领地，无论是投资，还是做别的。&lt;/p&gt;
&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>读书笔记 人生经验 投资 教育 罗杰斯</category>
      <guid isPermaLink="true">https://itindex.net/detail/48117-%E9%87%8F%E5%AD%90%E5%9F%BA%E9%87%91-%E5%88%9B%E5%A7%8B%E4%BA%BA-%E7%BD%97%E6%9D%B0%E6%96%AF</guid>
      <pubDate>Mon, 17 Feb 2014 18:30:05 CST</pubDate>
    </item>
    <item>
      <title>眼光，胸怀和实力 – 读《马云内部讲话》有感</title>
      <link>https://itindex.net/detail/47935-%E9%A9%AC%E4%BA%91-%E5%86%85%E9%83%A8</link>
      <description>&lt;p&gt;市面上关于马云的书很多，我挑选了马云内部讲话的I和II，现在读完了第一本，我想看看关键时刻马云说了一些什么话，为什么想看关于马云的书，主要源自于《赢在中国碧水蓝天间》，第一是马云是评委，那个大气的把握全局，已经大大压过了柳传志的气势。第二是姚劲波所学习对对象也是马云以及他的阿里巴巴。阿里巴巴的蚂蚁雄兵到现在十五年一直高速发展，基本上没怎样踩空过，虽然有各种质疑的声音，但是都这么一步步地走过来了，真是值得好好地看看。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;1. CEO应该经常地谈使命和价值观&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;这本书主要是05年到09年的五年左右时间里面对内部的各种场合的各种讲话，主要以阿里巴巴的B2B为主，我在他的演讲中看到最多的是关于阿里要做成什么样子的一家公司，一百零二年，最大的电子商务公司，客户第一，这样的声音不绝于耳。公司的vision，公司的目标，公司的策略，这些东西谁来讲最合适，CEO，并且要不厌其烦，一次次地说，难怪会形成某种宗教的感觉，当这些东西被烧进了脑子里面的时候，那么马云就是教主了，但是这又未尝不可，一百个成功的公司，一百个不同的做法，一百个不同的基因，成也基因败也基因，但是没有基因连成败的资格都没有，啥都不是。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;2. 男人的胸怀&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;马云不是没有错过，他也说过一些前后不对的话，但是他不会避讳这些东西，而是不断地修正去改变，比如他说过世界三大互联网公司中的一家，后来又改为了世界上最大的电子商务服务提供商，因为如果达到后者的话，前者其实基本达到的，而后者更加精确。他说过客户第一，员工第二，股东第三；他也说过客户第一，合作伙伴第二，员工第三，股东第四。他又说员工也是股东。他总有自己的解释，并且是能够让你信服的解释。他的批评总是很中肯，让人听得进去，比如说他批评大家在市长讲话的时候讲话，他用的是自己感觉难过，因为阿里人在大家心目中的形象毁掉了，这会让人感同身受。他一开始是说要让大家买房的，而之后又要年轻人去租房，他又用一种好方式让人听进去了。这就是情商，这就是说话的艺术。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;3. 不要怀念过去的美好，那只是幻想&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;阿里的文化是很强的，所以必定会出现融入的问题，在这个问题上，我看到的更多的是马云对于老员工的一次次的教育，不要去回忆过去的美好，那些美好没有那么真实。警告那些已经是百万富翁，千万富翁的人，其实现在还不够富，财富去得会很快。告诉那些老人，是因为聪明的都去了外面你们猜留下来，是因为坚持才会有了今天。当然个人对于他说的凡是出去的，没有看到成功的，这一点我表示怀疑，或者说这种方式不是很认同。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;4. 工作在高空和未来&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;马云的妙语连珠，来自于很多本质的思考，还有对于未来趋势的把握上。他肯定是不管实际的很多工作的，而实际的工作本身则需要各个公司上面都有负责人。他是CEO的CEO，所以他能够不管很多的执行工作，而通常来说CEO都是需要管具体的事情的。但是我觉得一个伟大的CEO还是需要工作在高空和未来，当然这个高空和未来需要更多的工作在地面和高空之间，把未来的高空看到的东西，变成能够执行的现实。&lt;/p&gt;
 &lt;p&gt;感受先写到这里，等看完下一本再继续写。&lt;/p&gt;
&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>读书笔记</category>
      <guid isPermaLink="true">https://itindex.net/detail/47935-%E9%A9%AC%E4%BA%91-%E5%86%85%E9%83%A8</guid>
      <pubDate>Thu, 06 Feb 2014 17:02:42 CST</pubDate>
    </item>
    <item>
      <title>从evernote和有道笔记转投OneNote 2013</title>
      <link>https://itindex.net/detail/48749-evernote-%E6%9C%89%E9%81%93-%E7%AC%94%E8%AE%B0</link>
      <description>&lt;p&gt;  &lt;a href="http://zhiqiang.org/blog/"&gt;博客&lt;/a&gt; »   &lt;a href="http://zhiqiang.org/blog/category/review"&gt;评论和笔记&lt;/a&gt; »   &lt;a href="http://zhiqiang.org/blog/tag/onenote" rel="tag"&gt;OneNote&lt;/a&gt; » &lt;/p&gt; &lt;p&gt;在记笔记方面，我最早用的是EverNote，后来用的是有道笔记，因为有道笔记的本地化做的更好，速度更快。3月15日，微软将OneNote 2013免费。我试用了一下，立马抛弃了我用了一年半的有道笔记，转投OneNote。&lt;/p&gt;
 &lt;p&gt;我转投OneNote最直接的理由是，OneNote对表格的支持更好，而表格是我在记笔记时用得最多的功能。而这几天在我使用OneNote的过程中，越发感到OneNote的方便和顺手。OneNote的最大的好处就是它能够用来整理资料和知识，而EverNote和有道笔记只适合用来收集资料（当作一个网络书签）。比如：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li value="1"&gt;OneNote的笔记层次为笔记本-分区-页，同时页又可以随意建立层次。这可以更方便地整理笔记。&lt;/li&gt;
  &lt;li&gt;在同一页笔记上， 也可以有很多的模块。从而可以进行复杂的排版，将东西整理成自己想要的样子。&lt;/li&gt;
  &lt;li&gt;外部PDF等各种文件可以直接打印到OneNote里，然后显示的内容上标注、记笔记等等。&lt;/li&gt;
  &lt;li&gt;OneNote会对图片做OCR并复制图片上的文字，并且支持搜索图片显示的文字。这让我可以随时截屏保存信息。&lt;/li&gt;
  &lt;li&gt;有很多快捷键可以用，这让OneNote基本可以全键盘操作，特别适合我的胃口。&lt;/li&gt;
  &lt;li&gt;跟有道笔记、EverNote一样，目前已经支持所有主流平台，windows、mac、iOS、andriod等等。它也有web界面，而且web界面的功能和软件是一样的，甚至更为强大，除了不支持某些快捷键外。&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;在使用过程中，我总结了一些方法和技巧如下：&lt;/p&gt;
 &lt;ul type="disc"&gt;
  &lt;li&gt;OneNote没有保存的概念，所有文档自动保存并同步到你的其它机器。不过免费版的历史版本功能被禁用，要回退到以前的历史版本，只能使用Ctrl+Z来撤销输入。&lt;/li&gt;
  &lt;li&gt;Ctrl+1可快速建立代办事项（文字前面会增加一个可勾选的方框），重复按Ctrl+1可以勾选该事项，再按一次取消该事项。Ctrl+2到9都是类似的功能。&lt;/li&gt;
  &lt;li&gt;分区和页都可以有层级结构。其中页可以有多层结构。页面的分层方法是直接拖动导航，根据缩紧定义分层结构。&lt;/li&gt;
  &lt;li&gt;重新打开OneNote后，上次更新的内容的背景色改为淡绿色，区块的右方会显示修改人，鼠标放上去后可查看修改时间以及修改人的更多信息。&lt;/li&gt;
  &lt;li&gt;Win+S为OneNote的截屏。截屏后可使用OneNote的OCR功能提取文字（点右键复制文字）。图片里的文字也是可以被搜索的（不需修改任何设置）。不过目前OCR并没有达到100%的准确度，不能100%的信赖。&lt;/li&gt;
  &lt;li&gt;OneNote支持模版。可建立模版，然后从模版建立新页面。我不确定模版是否会被同步。为了确保同步，我用的方法是直接将模版作为一个页面。当需要生成新页面时，我复制原来的页面即可（也可以按住Ctrl后用鼠标直接拖动）。&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;我也发现了一些缺陷和待解决的问题：&lt;/p&gt;
 &lt;ul type="disc"&gt;
  &lt;li&gt;字体设置对输入首英文字母无效。默认的calibri字体偏小，如果某段开始输入两个数字比如‘12’，其中1显示比2要小一点，看上去特别不协调。&lt;/li&gt;
  &lt;li&gt;同步速度是一个很大的问题，并且没有提示，我无法确定是否同步成功。而在手机上，我基本上没有在我想用的时候同步成功过。&lt;/li&gt;
  &lt;li&gt;部分快捷键无法在中文输入模式下使用，比如Ctrl+&amp;apos;.&amp;apos;建立无序列表。&lt;/li&gt;
  &lt;li&gt;表格内容无法垂直居中，无法合并单元格。&lt;/li&gt;
  &lt;li&gt;免费版缺少不少功能，收费版的价格太高。已知免费版缺少的功能有：
   &lt;ul type="circle"&gt;
    &lt;li&gt;从Excel文件导入和用Excel编辑表格&lt;/li&gt;
    &lt;li&gt;从Visio文件导入和用Visio编辑图标&lt;/li&gt;
    &lt;li&gt;录音和录像&lt;/li&gt;
    &lt;li&gt;历史页面功能。一旦笔记被错误改动然后关闭，将无法找回。Web编辑界面反而有历史版本的功能。&lt;/li&gt;
    &lt;li&gt;密码保护功能。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
 &lt;div&gt;
  &lt;p&gt; 附： 部分快捷键，有几个比如Alt+Shift+上下左右方向键，非常好用：&lt;/p&gt;
  &lt;div&gt;
   &lt;table border="1" cellpadding="0" cellspacing="0"&gt;

    &lt;tr&gt;
     &lt;td&gt;      &lt;strong&gt;操作&lt;/strong&gt;&lt;/td&gt;
     &lt;td&gt;      &lt;strong&gt;快捷键&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
     &lt;td&gt;新建笔记页&lt;/td&gt;
     &lt;td&gt;
      &lt;p&gt;Ctrl + N&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
     &lt;td&gt;插入链接&lt;/td&gt;
     &lt;td&gt;
      &lt;p&gt;Ctrl + K&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
     &lt;td&gt;使用项目符号（圆点）&lt;/td&gt;
     &lt;td&gt;
      &lt;p&gt;Ctrl + .&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
     &lt;td&gt;使用项目有序序号（1、2、3）&lt;/td&gt;
     &lt;td&gt;
      &lt;p&gt;Ctrl + /&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
     &lt;td&gt;应用标题式样（1到6）&lt;/td&gt;
     &lt;td&gt;
      &lt;p&gt;Ctrl + Alt +1-6&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
     &lt;td&gt;应用正文式样&lt;/td&gt;
     &lt;td&gt;
      &lt;p&gt;Ctrl + shift + N&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
     &lt;td&gt;左对齐（右对齐）&lt;/td&gt;
     &lt;td&gt;Ctrl + L（R）&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
     &lt;td&gt;增大（缩写）字体&lt;/td&gt;
     &lt;td&gt;Ctrl + Shift + &amp;gt;（&amp;lt;）&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
     &lt;td&gt;将当前段落或多个选定段落向上（下）移动。向上（下）移动选项卡&lt;/td&gt;
     &lt;td&gt;Alt+Shift+↑（↓）键&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
     &lt;td&gt;将当前段落或多个选定段落向左（右）移动（调整缩进）&lt;/td&gt;
     &lt;td&gt;Alt+Shift+←（→）键&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
     &lt;td&gt;插入当前日期和时间&lt;/td&gt;
     &lt;td&gt;
      &lt;p&gt;Alt + Shift + F&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
     &lt;td&gt;插入日期&lt;/td&gt;
     &lt;td&gt;
      &lt;p&gt;Alt + Shift + D&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
     &lt;td&gt;插入公式&lt;/td&gt;
     &lt;td&gt;
      &lt;p&gt;Alt + =&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
     &lt;td&gt;在当前列的右(左)侧创建一列&lt;/td&gt;
     &lt;td&gt;
      &lt;p&gt;Ctrl + Alt + R(E)&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
     &lt;td&gt;删除空行&lt;/td&gt;
     &lt;td&gt;
      &lt;p&gt;Del + Del&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
     &lt;td&gt;创建新行&lt;/td&gt;
     &lt;td&gt;
      &lt;p&gt;Enter&lt;/p&gt;
      &lt;p&gt;按两次结束表格&lt;/p&gt;
      &lt;p&gt;在开头处按Enter在上方创建新行&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
     &lt;td&gt;调整选项卡宽度&lt;/td&gt;
     &lt;td&gt;
      &lt;p&gt;Ctrl + Shift + [ or ]&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
     &lt;td&gt;创建新页&lt;/td&gt;
     &lt;td&gt;
      &lt;p&gt;Ctrl + Alt + N&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
     &lt;td&gt;创建新子页&lt;/td&gt;
     &lt;td&gt;
      &lt;p&gt;Ctrl + Alt + Shift + N&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
     &lt;td&gt;向上翻页&lt;/td&gt;
     &lt;td&gt;
      &lt;p&gt;Ctrl + PageDown(Up)&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
     &lt;td&gt;焦点放到当前选项卡上&lt;/td&gt;
     &lt;td&gt;
      &lt;p&gt;Ctrl + Alt + G&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
     &lt;td&gt;以黄色突出显示所选文字。&lt;/td&gt;
     &lt;td&gt;Ctrl+Shift+H或 Ctrl+Alt+H&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
     &lt;td&gt;打开OneNote&lt;/td&gt;
     &lt;td&gt;
      &lt;p&gt;Win + Shift + N&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
     &lt;td&gt;截屏&lt;/td&gt;
     &lt;td&gt;
      &lt;p&gt;Win + S&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;div&gt;  &lt;h4&gt;相关文章&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;    &lt;a href="http://zhiqiang.org/blog/review/begin-onenote-over-youdao-evernote.html"&gt;从evernote和有道笔记转投OneNote 2013&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;     &lt;p&gt;&lt;/p&gt;
     &lt;hr&gt;&lt;/hr&gt;
     &lt;p&gt;© 张志强 for   &lt;a href="http://zhiqiang.org/blog"&gt;阅微堂&lt;/a&gt;, 2014. |   &lt;a href="http://zhiqiang.org/blog/review/begin-onenote-over-youdao-evernote.html"&gt;链接&lt;/a&gt; |   &lt;a href="http://zhiqiang.org/blog/review/begin-onenote-over-youdao-evernote.html#comments"&gt;3 条评论&lt;/a&gt;&lt;/p&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>评论和笔记 OneNote</category>
      <guid isPermaLink="true">https://itindex.net/detail/48749-evernote-%E6%9C%89%E9%81%93-%E7%AC%94%E8%AE%B0</guid>
      <pubDate>Thu, 27 Mar 2014 19:30:05 CST</pubDate>
    </item>
    <item>
      <title>GTD如何进行项目分解</title>
      <link>https://itindex.net/detail/47301-gtd-%E4%BD%95%E8%BF%9B-%E9%A1%B9%E7%9B%AE</link>
      <description>&lt;p&gt;
　　GTD的第一个核心是收集，收集系统的设计是为了保证注意力的集中（心静如水）。GTD的第二个核心就是下一步行动清单，下一步行动清单的设计是为了保证可执行性。这里的关键是项目分解。&lt;/p&gt;
 &lt;p&gt;
　　很多GTD执行不到位的案例，问题都出在项目分解这一环。有些初学者把工作篮里的事项拿过来直接丢进下一步行动清单，而这些事项往往不具备可执行性。&lt;/p&gt;
 &lt;p&gt;
　　比如，做销售的朋友，经常会有“和某客户的负责人建立人际关系”这样的工作内容。这种事情一般来说不是一个简单的行动能够搞定的。如果你把这一个事情丢在下一步行动清单里，每当你看到它的时候，你打算怎么做呢？最有可能出现的情况是，你觉得它太复杂了，先放着，先去做别的事情。这样一来，拖延也就成为必然的选择。&lt;/p&gt;
 &lt;p&gt;
　　不具备直接的可执行性，就不应当进下一步行动清单，这是ＧＴＤ的一个原则。分解复杂项目的能力，就是办事能力。诸葛亮未出茅庐，就把取天下这样一个极为复杂的项目做了分解：先取荆州后取川。当然这是一个宏观层面的分解，具体执行的时候，还有许多的细节，都必须一步一步地分解。多看看《三国演义》中诸葛亮分兵派将的细节，对于提高项目分解能力会有很大帮助。&lt;/p&gt;
 &lt;p&gt;
　　有的时候，任务过于复杂，深入的情况我们事先也未必了解，想完全分解很困难，那我们应该进行最基本的分解：把第一步行动提取出来，也就是所谓的“下一步”。对于每个项目，至少分解为“下一步”和“其它内容”两部分。而其中“下一步”必须是可以直接执行的。事实上，所谓的“下一步行动清单”，也就是这个意思。等到这一步完成之后，再继续分解，继续推进。&lt;/p&gt;
 &lt;p&gt;　　按这个节奏，再复杂的任务也能一步一步地完成。  &lt;br /&gt;&lt;/p&gt; &lt;br /&gt; &lt;img src="http://simg.sinajs.cn/blog7style/images/special/1265.gif"&gt;&lt;/img&gt;  &lt;a href="http://sina.allyes.com/main/adfclick?db=sina&amp;bid=204720,469641,474922&amp;cid=0,0,0&amp;sid=473458&amp;advid=358&amp;camid=37389&amp;show=ignore&amp;url=http://qing.blog.sina.com.cn/tag/%E5%86%99%E7%9C%9F" target="_blank"&gt;青春就应该这样绽放&lt;/a&gt;   &lt;a href="http://sina.allyes.com/main/adfclick?db=sina&amp;bid=204720,469645,474926&amp;cid=0,0,0&amp;sid=473464&amp;advid=358&amp;camid=37389&amp;show=ignore&amp;url=http%3A%2F%2Funion.9173.com%2Fpub%3Fp%3D1%26u%3D1008" target="_blank"&gt;游戏测试：三国时期谁是你最好的兄弟！！&lt;/a&gt;   &lt;a href="http://sina.allyes.com/main/adfclick?db=sina&amp;bid=204720,469646,474927&amp;cid=0,0,0&amp;sid=473465&amp;advid=358&amp;camid=37389&amp;show=ignore&amp;url=http://qing.blog.sina.com.cn/tag/%E6%98%9F%E5%BA%A7" target="_blank"&gt;你不得不信的星座秘密&lt;/a&gt; &lt;img src="http://sina.allyes.com/main/adfclick?db=sina&amp;bid=204720,470173,475454&amp;cid=0,0,0&amp;sid=474001&amp;advid=358&amp;camid=37389&amp;show=ignore&amp;url=http://simg.sinajs.cn/blog7style/images/common/sg_trans.gif?t=0"&gt;&lt;/img&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>GTD笔记本应用</category>
      <guid isPermaLink="true">https://itindex.net/detail/47301-gtd-%E4%BD%95%E8%BF%9B-%E9%A1%B9%E7%9B%AE</guid>
      <pubDate>Sat, 28 Dec 2013 07:48:38 CST</pubDate>
    </item>
    <item>
      <title>用上20M光纤的之后</title>
      <link>https://itindex.net/detail/39979-20m-%E5%85%89%E7%BA%A4</link>
      <description>　　今年中秋国庆节，完成了可谓人生中最重要的事情，买房，搬家住新房。终于从脏脏的小巷子搬到了漂亮的公寓楼房。也就此伦为了房奴，接受每个月惊心动魄的按揭贷款还债…… &lt;br /&gt;　　这段时间可能大家会觉得我太懒了，更新软件不够及时，其实是在为上述事情奔波，趁着这个假期办完该办的事情，也可以安下心来做工作。 &lt;br /&gt;　　最重要的网络问题一定要解决。之前住的地方比较偏僻，无光纤，拉的是4M ADSL，网络不够稳定。现在移到这边，直接改成了光纤，4M光纤加上普清机顶盒，实际上速度已经比以前更快，因为ADSL的铜线损耗实在是太大了，光纤几乎是零损耗。而普清机顶盒放在大彩电，比例明显是不对称的，人被压扁，那感觉非常不舒服。于是便上营业厅咨询，业务员称必须要装12M带宽以上才可以装高清机顶盒，然后看看价格，20M带宽比12M带宽只每月贵20元。那我就直接装个20M的得了。中国电信在这个区域的服务态度和在以前住的偏僻地方简直是有天壤之别，响应非常快，预约第二天师傅便上门改装，更换机顶盒，用HDMI线接入，高清电视终于来了，网络也变成了20M。现在迅雷下载速度达到2.5MB/S以上，只是上传仍是限制在了512KB（这没办法，广州全城都是这样，普通宽带上传速度限制得非常厉害，除非是企业宽带，那可就是上下行一样的速度）。接入高清机顶盒之后，自带了几个高清频道，如湖南卫视高清、CCTV高清、CCTV-1高清、浙江卫视高清、江苏卫视高清、深圳卫视高清、黑龙江卫视高清、北京卫视高清、广东卫视高清、东方卫视高清等等。这高清看得是把人的脸毛细孔都看得出来了，我妈说看得都不太习惯了，太清晰了感觉人的皱纹都出来了，人也拉长了，这也难怪，她已经看普清压扁的尺寸习惯了另外还有百多个普清频道可看。更神奇的一个功能便是回看功能，能够随时看前2天的电视节目，时光倒流看错过的节目，此外还有点播节目，更可以看高清电影电视（有些要额外包月收费的），还有游戏通讯功能等。看来以后电视便是一个云终端啰。有线电视可以扔到一边去了。 &lt;br /&gt;　　总之，光纤的生活真爽！赶紧全国普及吧。 &lt;br /&gt;Tags -  &lt;a href="http://it.oyksoft.com/tags/%25E5%2585%2589%25E7%25BA%25A4/" rel="tag"&gt;光纤&lt;/a&gt; ,  &lt;a href="http://it.oyksoft.com/tags/%25E9%25AB%2598%25E6%25B8%2585/" rel="tag"&gt;高清&lt;/a&gt;

&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>随手笔记</category>
      <guid isPermaLink="true">https://itindex.net/detail/39979-20m-%E5%85%89%E7%BA%A4</guid>
      <pubDate>Fri, 05 Oct 2012 10:41:32 CST</pubDate>
    </item>
    <item>
      <title>复习、考试技巧大汇总帮你搞定期末考试</title>
      <link>https://itindex.net/detail/41257-%E8%80%83%E8%AF%95-%E6%8A%80%E5%B7%A7-%E6%80%BB%E5%B8%AE</link>
      <description>&lt;p&gt;  &lt;img src="https://6ts4ug.blu.livefilestore.com/y1pssslnnnFrrTlXgNktybn6ZVHua0fD_OqFFIwdLUfnmNj-F7KqRfAv0jbU-VnjMk6Ot5iU6mgQIQ/2010051600005321.jpg?psid=1"&gt;&lt;/img&gt; &lt;/p&gt;
 &lt;p&gt;看到一些留言才发现，又快期末考试了，特意汇总了多篇复习、考试的文章，希望对要考试的人有所帮助：&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;还有1-2周就要考试了，应该怎么办？：&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt; &lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;   &lt;a href="http://www.read.org.cn/html/256-if-only-from-examination-of-the-10-to-16-day.html"&gt;应试学习系列－－如果离考试只有10到16天了&lt;/a&gt; &lt;/li&gt;
  &lt;li&gt;   &lt;a href="http://www.read.org.cn/html/257-if-only-from-examination-of-the-10-to-16-day-2.html"&gt;应试学习系列－－如果离考试只有10到16天了(2)&lt;/a&gt; &lt;/li&gt;
  &lt;li&gt;   &lt;a href="http://www.read.org.cn/html/308-if-only-from-examination-of-the-6-to-9-day-1.html"&gt;应试学习系列－－如果离考试只有６到９天了（１）&lt;/a&gt; &lt;/li&gt;
  &lt;li&gt;   &lt;a href="http://www.read.org.cn/html/309-if-only-from-examination-of-the-6-to-9-day-2.html"&gt;应试学习系列－－如果离考试只有６到９天了（2）&lt;/a&gt; &lt;/li&gt;
  &lt;li&gt;   &lt;a href="http://www.read.org.cn/html/340-if-only-from-examination-of-the-2-to-5-day-1.html"&gt;应试学习系列－－如果离考试只有２到５天了（１）&lt;/a&gt; &lt;/li&gt;
  &lt;li&gt;   &lt;a href="http://www.read.org.cn/html/342-if-only-from-examination-of-the-2-to-5-day-2.html"&gt;应试学习系列－－如果离考试只有２到５天了（２）&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;  &lt;strong&gt;你想知道怎样复习效果会更好吗：&lt;/strong&gt;&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;   &lt;a href="http://www.read.org.cn/html/191-how-more-effective-review-1.html"&gt;怎样更有效的复习（１）&lt;/a&gt; &lt;/li&gt;
  &lt;li&gt;   &lt;a href="http://www.read.org.cn/html/193-how-more-effective-review-2.html"&gt;怎样更有效的复习（2）&lt;/a&gt; &lt;/li&gt;
  &lt;li&gt;   &lt;a href="http://www.read.org.cn/html/353-review-of-time-management-in-the-course-of-the-seven-major-taboo.html"&gt;复习过程中时间管理七大禁忌&lt;/a&gt; &lt;/li&gt;
  &lt;li&gt;   &lt;a href="http://www.read.org.cn/html/356-accord-with-the-review-tactics-to-study-law.html"&gt;符合学习规律的复习策略&lt;/a&gt; &lt;/li&gt;
  &lt;li&gt;   &lt;a href="http://www.read.org.cn/html/362-to-improve-learning-and-memory-in-super-review-act.html"&gt;改善记忆的超级学习复习法&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;  &lt;strong&gt;应试技巧？&lt;/strong&gt;&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;   &lt;a href="http://www.read.org.cn/html/301-how-to-lift-the-spirit-of-the-pressure-test.html"&gt;怎样解除考试的精神压力&lt;/a&gt; &lt;/li&gt;
  &lt;li&gt;   &lt;a href="http://www.read.org.cn/html/303-every-20-minutes-a-replacement-subjects.html"&gt;高效学习小技巧之&amp;quot;每20分钟更换一次科目&amp;quot;&lt;/a&gt; &lt;/li&gt;
  &lt;li&gt;   &lt;a href="http://www.read.org.cn/html/378-6_things_to_remember_when_cramming_for_finals.html"&gt;为期末考试而努力时应记住的六点&lt;/a&gt; &lt;/li&gt;
  &lt;li&gt;   &lt;a href="http://www.read.org.cn/html/546-students-take-part-in-a-cup-of-water-before-the-exam-can-play-better.html"&gt;考试小技巧－－学生参加考试前喝杯水可发挥更出色&lt;/a&gt; &lt;/li&gt;
  &lt;li&gt;   &lt;a href="http://www.read.org.cn/html/519-test-without-too-2.html"&gt;《考无不胜》心得（2）－对付考试的一般学习方法&lt;/a&gt; &lt;/li&gt;
  &lt;li&gt;   &lt;a href="http://www.read.org.cn/html/683-improve-the-learning-efficiency-of-the-night.html"&gt;提高夜晚学习效率的建议&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;  &lt;strong&gt;如果你喜欢笔记来复习，一定要看看这个：&lt;/strong&gt;&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;   &lt;a href="http://www.read.org.cn/html/711-the-worldu002639s-best-way-to-review-notes.html"&gt;世界上最好的复习笔记方法&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;一般来说思维导图做笔记更直观一些，使用六色荧光笔学习法最节省时间。康奈尔笔记做制作更好看。这三种方法可以根据个人需要来选择和应用&lt;/p&gt;
 &lt;p&gt; &lt;/p&gt;
 &lt;hr&gt;&lt;/hr&gt;
 &lt;p&gt;本Blog开通微信平台：微信号码   &lt;strong&gt;read01 &lt;/strong&gt;用微信的可以关注一下。&lt;/p&gt;
 &lt;p&gt;   &lt;img border="0" src="https://xfxkia.blu.livefilestore.com/y1pb7QzjJUXzlHsL2XLnFy_uAekSEJxwobuOVZMe6XcisZvtqEKe0a6Lha5k7PH2TFNdxy2hB4XBM4/%E5%BE%AE%E4%BF%A1%E4%BA%8C%E7%BB%B4%E7%A0%81.jpg?psid=1"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;转载本站文件请保留原始链接。&lt;/p&gt;
 &lt;p&gt;我现在经常在微博上出现，欢迎大家利用微博和豆瓣来提问，我尽量找时间来回复，如果没有马上回复是因为时间关系，请耐心等待一下。&lt;/p&gt;
 &lt;p&gt;如果你觉得我分享的东西不错，请关注我：  &lt;strong&gt;1、   &lt;a href="http://weibo.com/warfalcon"&gt;新浪&lt;/a&gt; 2、   &lt;a href="http://www.douban.com/people/warfalcon/"&gt;豆瓣&lt;/a&gt; 3、   &lt;a href="http://t.qq.com/warfalcon"&gt;腾讯&lt;/a&gt; 4、&lt;/strong&gt;  &lt;a href="http://www.twitter.com/warfalcon"&gt;Twitter&lt;/a&gt; 5、  &lt;a href="http://www.zhihu.com/people/warfalcon"&gt;知乎&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;如果你对思维导图感兴趣，可以看看我的另一个Blog，  &lt;a href="http://www.write.org.cn/"&gt;http://www.write.org.cn&lt;/a&gt; 已经提供了100多本图书的思维导图源文件下载，欢迎访问和定阅。&lt;/p&gt;
 &lt;p&gt;发现本Blog在国内的部分城市无法访问，请用RSS或邮件进行定阅，便于阅读。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;读书笔记：&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;RSS地址：   &lt;a href="http://feed.write.org.cn/"&gt;http://feed.write.org.cn&lt;/a&gt;  Web:   &lt;a href="http://www.write.org.cn/"&gt;http://www.write.org.cn&lt;/a&gt; QQ邮箱请点击  &lt;a href="http://mail.qq.com/cgi-bin/bookcol?colid=20039"&gt;   &lt;img alt="&amp;#35746;&amp;#38405;&amp;#21040;QQ&amp;#37038;&amp;#31665;" border="0" src="http://rescdn.qqmail.com/zh_CN/dy/btn_dyrss.gif"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;战隼的学习探索：&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;RSS地址：   &lt;a href="http://feed.read.org.cn/"&gt;http://feed.read.org.cn&lt;/a&gt;  Web:   &lt;a href="http://www.read.org.cn/"&gt;http://www.read.org.cn&lt;/a&gt; QQ邮箱请点击   &lt;img alt="&amp;#35746;&amp;#38405;&amp;#21040;QQ&amp;#37038;&amp;#31665;" border="0" src="http://rescdn.qqmail.com/zh_CN/dy/btn_dyrss.gif"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;table border="0" cellpadding="2" cellspacing="0" width="100%"&gt;
    
      &lt;tr&gt;
           &lt;td&gt;    &lt;strong&gt;您可能也喜欢：&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    
              &lt;tr&gt;
                   &lt;td&gt;
                        &lt;img border="0" src="http://static.wumii.cn/images/widget/widget_solidPoint.gif"&gt;&lt;/img&gt;
                        &lt;a href="http://app.wumii.com/ext/redirect?url=http%3A%2F%2Fwww.read.org.cn%2Fblog%2F2008%2F04%2F18%2Fif-only-from-examination-of-the-2-to-5-day-2%2F&amp;from=http%3A%2F%2Fwww.read.org.cn%2Fhtml%2F2114-fu-xi-kao-shi-ji-qiao-da-hui-zong-bang-ni-gao-ding-qi-mo-kao-shi.html" target="_blank"&gt;
                        应试学习系列－－如果离考试只有２到５天了（２）
                    &lt;/a&gt;
                &lt;/td&gt;
            &lt;/tr&gt;
              &lt;tr&gt;
                   &lt;td&gt;
                        &lt;img border="0" src="http://static.wumii.cn/images/widget/widget_solidPoint.gif"&gt;&lt;/img&gt;
                        &lt;a href="http://app.wumii.com/ext/redirect?url=http%3A%2F%2Fwww.read.org.cn%2Fhtml%2F309-if-only-from-examination-of-the-6-to-9-day-2.html&amp;from=http%3A%2F%2Fwww.read.org.cn%2Fhtml%2F2114-fu-xi-kao-shi-ji-qiao-da-hui-zong-bang-ni-gao-ding-qi-mo-kao-shi.html" target="_blank"&gt;
                        应试学习系列－－如果离考试只有６到９天了（2）
                    &lt;/a&gt;
                &lt;/td&gt;
            &lt;/tr&gt;
              &lt;tr&gt;
                   &lt;td&gt;
                        &lt;img border="0" src="http://static.wumii.cn/images/widget/widget_solidPoint.gif"&gt;&lt;/img&gt;
                        &lt;a href="http://app.wumii.com/ext/redirect?url=http%3A%2F%2Fwww.read.org.cn%2Fhtml%2F544-use-mind-mapping-to-help-you-study-and-pass-the-exam-express-2.html&amp;from=http%3A%2F%2Fwww.read.org.cn%2Fhtml%2F2114-fu-xi-kao-shi-ji-qiao-da-hui-zong-bang-ni-gao-ding-qi-mo-kao-shi.html" target="_blank"&gt;
                        使用思维导图来帮助你快速学习和通过考试（2）
                    &lt;/a&gt;
                &lt;/td&gt;
            &lt;/tr&gt;
              &lt;tr&gt;
                   &lt;td&gt;
                        &lt;img border="0" src="http://static.wumii.cn/images/widget/widget_solidPoint.gif"&gt;&lt;/img&gt;
                        &lt;a href="http://app.wumii.com/ext/redirect?url=http%3A%2F%2Fwww.read.org.cn%2Fhtml%2F2100-wang-tseen-de-gao-ding-wu-ya-gong-zuo-de-yi-shu-bi-ji-ji-shi-jian-xin-de-fen-xiang.html&amp;from=http%3A%2F%2Fwww.read.org.cn%2Fhtml%2F2114-fu-xi-kao-shi-ji-qiao-da-hui-zong-bang-ni-gao-ding-qi-mo-kao-shi.html" target="_blank"&gt;
                        网友tseen的《搞定I：无压工作的艺术》笔记及实践心得分享
                    &lt;/a&gt;
                &lt;/td&gt;
            &lt;/tr&gt;
    
      &lt;tr&gt;
           &lt;td align="right"&gt;
                &lt;a href="http://www.wumii.com/widget/relatedItems" target="_blank" title="&amp;#26080;&amp;#35269;&amp;#30456;&amp;#20851;&amp;#25991;&amp;#31456;&amp;#25554;&amp;#20214;"&gt;
                无觅
            &lt;/a&gt;
        &lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>推荐资源 复习 复习笔记 ， 应试学习系列 考试技巧</category>
      <guid isPermaLink="true">https://itindex.net/detail/41257-%E8%80%83%E8%AF%95-%E6%8A%80%E5%B7%A7-%E6%80%BB%E5%B8%AE</guid>
      <pubDate>Thu, 20 Dec 2012 08:52:12 CST</pubDate>
    </item>
    <item>
      <title>读《爆发》-行为预测</title>
      <link>https://itindex.net/detail/41251-%E8%A1%8C%E4%B8%BA-%E9%A2%84%E6%B5%8B</link>
      <description>预测之准确性有两个方面的内容，一个是前期大量采集样本数据的积累，一个是预测模型，而预测模型本身又是通过前期不断预测和修正逐步精确的。预测不可能100%准确，但是我们能够增加预测准确性的概率。由于混沌理论和不确定性，预测复杂度不断增加，特别是对结果造成影响的各个X因子会越来越多，有些X因子可知但是基于样本，有些X因子其本身就还处于未知和探索阶段。 &lt;br /&gt;

 &lt;br /&gt;
人类行为产生的数据是典型的大数据，那么人类行为的可预测性首先在于数据的采集和清理上面，但是客观要能够反映主观不仅仅是数据层面的问题，更多的是对人类行为动机分析上面。 &lt;br /&gt;

 &lt;br /&gt;
泊松分布主要用于研究单位时间或单位空间内某事件的发生数，理论上单位时间或单位空间内的发生数可为无穷大。泊松分布基于事件独立，离散和随机分布。但是当我们的样本数据足够大的时候，发现偶然和随机之中有其规律。泊松将不可预测性和偶然性等同而语，一旦我们承认人类行为是随机的，它突然之间就可以被预测了？ &lt;br /&gt;

 &lt;br /&gt;
人类行为如果真可以预测？说实话很难说真正是好事还是坏事，很多时候我们不断的探索和寻找，正是存在着某种不确定性和不可预测性，我们的行为往往才更加存在价值。书里面提到的一个概念，即93%是可以预测的，暂时还没有看到后面这个数据具体的来源。 &lt;br /&gt;

 &lt;br /&gt;
我们看到预测本身又分为短期和长期，有时候是分析长期趋势容易，分析短期波动困难，如大经济预测。有时候又是预测近期容易，预测远期困难，如天气预测。人类行为之预测正是长远期困难，其一个重要原因是远期预测往往基于中期预测之多个因子，中期预测的细微偏差都直接导致了远期预测的巨大偏离。 &lt;br /&gt; &lt;br /&gt; &lt;img src="http://simg.sinajs.cn/blog7style/images/special/1265.gif"&gt;&lt;/img&gt;  &lt;a href="http://sina.allyes.com/main/adfclick?db=sina&amp;bid=204720,469641,474922&amp;cid=0,0,0&amp;sid=473458&amp;advid=358&amp;camid=37389&amp;show=ignore&amp;url=http://qing.weibo.com/tag/%E5%86%99%E7%9C%9F" target="_blank"&gt;青春就应该这样绽放&lt;/a&gt;   &lt;a href="http://sina.allyes.com/main/adfclick?db=sina&amp;bid=204720,469645,474926&amp;cid=0,0,0&amp;sid=473464&amp;advid=358&amp;camid=37389&amp;show=ignore&amp;url=http%3A%2F%2Funion.9173.com%2Fpub%3Fp%3D1%26u%3D1008" target="_blank"&gt;游戏测试：三国时期谁是你最好的兄弟！！&lt;/a&gt;   &lt;a href="http://sina.allyes.com/main/adfclick?db=sina&amp;bid=204720,469646,474927&amp;cid=0,0,0&amp;sid=473465&amp;advid=358&amp;camid=37389&amp;show=ignore&amp;url=http://qing.weibo.com/tag/%E6%98%9F%E5%BA%A7" target="_blank"&gt;你不得不信的星座秘密&lt;/a&gt; &lt;img src="http://sina.allyes.com/main/adfclick?db=sina&amp;bid=204720,470173,475454&amp;cid=0,0,0&amp;sid=474001&amp;advid=358&amp;camid=37389&amp;show=ignore&amp;url=http://simg.sinajs.cn/blog7style/images/common/sg_trans.gif?t=0"&gt;&lt;/img&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>读书笔记</category>
      <guid isPermaLink="true">https://itindex.net/detail/41251-%E8%A1%8C%E4%B8%BA-%E9%A2%84%E6%B5%8B</guid>
      <pubDate>Wed, 19 Dec 2012 22:05:21 CST</pubDate>
    </item>
    <item>
      <title>用心理学知识考好试</title>
      <link>https://itindex.net/detail/44702-%E5%BF%83%E7%90%86%E5%AD%A6-%E7%9F%A5%E8%AF%86</link>
      <description>&lt;h3&gt;  &lt;img alt="" height="181" src="http://www.testinteligencia.net/image/repository/test1.jpg" width="329"&gt;&lt;/img&gt;&lt;/h3&gt;
 &lt;h3&gt;实在不会答题怎么办？&lt;/h3&gt;
 &lt;p&gt;考试中的悲剧是遇到论述题没有复习到，那就放弃吗？不，可以这样答：&lt;/p&gt;
 &lt;p&gt;一是赞美着答，出题人潜意识中会觉得自己出题好，往往对问答内容的意义设置采分点，所以先说问得好。&lt;/p&gt;
 &lt;p&gt;二是举例着答，不会问题，编个例子总会混几分的，不要空着，但忌开篇举例，那说明你除了例子，什么都不会。&lt;/p&gt;
 &lt;p&gt;三是辨证着答，辩证法虽无实用价值，但答题却非常给力。文科类的问题影响因素众多，你可以说完东说西，常用句式有“一方面……，另一方面……”“……有价值（优点），但要注意到（谈缺点），”，“我们既要看到……，也要看到……，同时要避免……”，对，关键就是说正确的废话。&lt;/p&gt;
 &lt;h3&gt;忘记答案怎么办？&lt;/h3&gt;
 &lt;p&gt;如果简答题5条只记得4条，把1、4条重复写，6条答案记5条，2、4（5）条重复写。其中的心理原因是：人们在记忆时，后面内容受前面的影响，前面内容受后面的影响，中间内容前后受影响；依此规律，在中间偏后的部分重复答案最易混过关，这也是记字母歌的时候ABC，XYZ很快学会，中间的opq之类记得慢的原因。专业上的名字叫要前摄抑制和倒摄抑制，前者说的是前面学的知识对后面的影响，后面说的是后面学习的知识对前面的影响。&lt;/p&gt;
 &lt;p&gt;一个观点写两次不会出问题吗？从教师批改试卷的心理来分析，批改试卷是一件效率优先的工作，当老师的都希望能更快地把试卷判完，这样他（她）会不由自主地简化认知加工过程，比如，判卷老师面对答案时主要做“是否判断”，即采分点出现过没有，出现即给分；但一般不会做“再认判断”，即这个答案出现过没有，因为很少会有学生同一个答案写满所有题，教师不会在判卷时排查这一点。所以虽然一个采分点写了两次，但判卷老师稍不留神你就过关了。&lt;/p&gt;
 &lt;h3&gt;笑谈考前准备&lt;/h3&gt;
 &lt;p&gt;当然，如果考前有所准备会更好一些，如买一个鸭梨放入冰箱，变“压力（鸭梨）”为“动力（冻梨）”；吃点小食品锅巴，意为“过吧”，防止挂科；最后，考试当天穿耐克，因为Nike的标志是个“√”，能保证成功率，最好不要穿特步，因为特步的标志是个“×”……其实，这里涉及的是自我暗示的知识，在某些情况下，自我暗示确实起作用的，那些考前拜拜神之类的也不能说都不灵的。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;附赠小贴士一条&lt;/strong&gt;：如果你恨一个男人，就在考试之前说你暗恋他。&lt;/p&gt;
&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>心理随笔 教研札记 管理影响 心理分析 教师心理</category>
      <guid isPermaLink="true">https://itindex.net/detail/44702-%E5%BF%83%E7%90%86%E5%AD%A6-%E7%9F%A5%E8%AF%86</guid>
      <pubDate>Fri, 28 Jun 2013 21:36:15 CST</pubDate>
    </item>
    <item>
      <title>考试过关必胜笔记法</title>
      <link>https://itindex.net/detail/34191-%E8%80%83%E8%AF%95-%E7%AC%94%E8%AE%B0</link>
      <description>&lt;p&gt;很不错的文章，跟大家分享一下。有一本书叫《東大合格生筆記大公開》里面介绍的记笔记的方法非常的详细，书看完了，笔记一直没做完，找时候把这本书的笔记做完分享一下，跟这篇文章差不多。&lt;/p&gt;
&lt;p&gt;转自：&lt;a href="http://article.yeeyan.org/view/266896/234209"&gt;http://article.yeeyan.org/view/266896/234209&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;作者：破小芙&lt;/p&gt;
&lt;p&gt;应试专家横沟慎一郎提出了一种“考试过关必胜笔记法”，包含2册笔记，一册&lt;b&gt;《学习时间管理笔记》&lt;/b&gt;，另一册&lt;b&gt;《难题笔记》&lt;/b&gt;。到底这是怎么回事儿呢？学生族，或一边工作一边进修的上班族们，尤其是那些要在短期内通过某某考试，取得合格的朋友，下面的内容也许会令你们感兴趣。&lt;/p&gt;

&lt;p&gt;要在短期内取得一项证书，确保学习时间是最重要的。所以首先，第一册笔记上，画上日常时间分配的饼图、来重新审视一下自己的时间管理利用吧！“你会发现，其实能用作学习的时间，比你想象中的要多很多。”横沟说道，最好在双休日作好饼图，以确保下一周的学习时间。一天的学习结束后，实际上学了多少时间、看掉多少页数，也请一一记录在案。这样能精确的把握自己前进的步伐，有落下的也能及时发现和赶上。&lt;/p&gt;
&lt;p&gt;第二册的《难题笔记》，是专门为克服错题难题而作的。抄上问题，然后反复温习操练，直到完全掌握。那些重复犯错的地方，可以划线和N次贴特别标示。这样临考前，重点看贴着N次贴的部分就可以了。&lt;/p&gt;

&lt;p&gt;下面我们来看看具体实例。&lt;/p&gt;
&lt;p&gt;&lt;b&gt;一。第一册《学习时间管理笔记》&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;这册笔记的目的，是为了发掘出尽可能多的学习时间和机会。在左页饼图中划出可以用来学习的时间带。从右页开始，记录实际的学习时间和进度，比如页数，等等。&lt;/p&gt;
&lt;p&gt;&lt;img border="0" alt="" src="http://photo.staticsdo.com/a1/466/393/510/83989-1453314369-8.jpg"&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt; 如图中(1)-(7)所示。&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;(1)空出一些休闲时间&lt;/p&gt;
&lt;p&gt;一个劲儿的猛学效率反而低，所以请留出一些时间让自己放松一下。图中是用橙色表示，你也可以涂上任何你喜欢的颜色。&lt;/p&gt;
&lt;p&gt;(2)决定学习时间段，涂色&lt;/p&gt;
&lt;p&gt;睡眠、工作这种肯定没办法学习的时间段，涂上黑线。接下来就要决定必须用来学习的时间段了，图中涂绿色表示的即是。比如，晚饭后2小时、睡前1小时，作者决定这3个小时必须用来学习。&lt;/p&gt;
&lt;p&gt;(3)灵活机动的时间段，现场检验&lt;/p&gt;
&lt;p&gt;通勤路上、午餐时间这种，比较灵活机动的时间段再用另一种颜色标出。然后关键来了——写上“抽出○○分钟学习为目标”，然后现场检验，看看是否这些时间段也能稍微利用一下？&lt;/p&gt;
&lt;p&gt;(4)每周周头写上计划和目标&lt;/p&gt;
&lt;p&gt;希望达到的学习时间、看完参考书的页数在每周周头写入笔记吧。如果对上周有反省，有新的目标，也一起记入。这样等于起了个好头，接下来照着做就行。&lt;/p&gt;
&lt;p&gt;(5)倒计时&lt;/p&gt;
&lt;p&gt;离目标实现还剩多少时间？也写下来。这样可以知道自己的进度，而且如果哪天偷懒了，写下倒计时，也能有助于自我反省和激励。&lt;/p&gt;
&lt;p&gt;(6)当天的学习情况记录&lt;/p&gt;
&lt;p&gt;当天学了多久？看了多少页？目标倒计时还有几天？除了记这些，还可以用○△×的符号来评价当天的学习情况，是优良？中等？还是差？这样日积月累，翻一下笔记，就可以大致知道自己的进度是比较令人满意的，还是有点跟不上了……&lt;/p&gt;
&lt;p&gt;(7)周日回顾&lt;/p&gt;
&lt;p&gt;每周日回顾笔记，看看学习是否按计划顺利进行了？目标达成了，就用彩色笔画上装饰，或写上“吃蛋糕奖励自己”，提高自己的斗志，迎接下周挑战。如果目标没有达成，也不用气馁，按实际情况调整下周作战计划吧！&lt;/p&gt;
&lt;p&gt;&lt;b&gt;二。第二册《难题笔记》&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;第二册《难题笔记》是专门用来补缺补差的。把做错的题、不懂得题和其正确答案写上，再自己做一遍，对答案。如果错了，就用彩色笔纠正。再练习一遍，如果又错了，就换一支彩色笔划线做记号，贴N次贴。这样明确了自己的弱点所在，临考前的复习也更有针对性，更简单。&lt;/p&gt;
&lt;p&gt;&lt;img border="0" alt="" src="http://photo.staticsdo.com/a1/466/294/220/83990-1453314369-8.jpg"&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;如图中(1)-(4)所示。&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;左页(1)是问题，右页(2)是对应的正确答案。抄好后自己做一遍可以加深理解。当然，也可以用复印的。但最好还是自己手抄一遍加深印象。&lt;/p&gt;
&lt;p&gt;自己解题第一遍错了，就像(3)那样用其他颜色的笔加上说明解释。再做一遍，如果继续错，就在反复犯错的地方(4)贴上N次贴来强调。 &lt;/p&gt;
&lt;p&gt;&lt;b&gt;三。笔记本的选择&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;最好是螺线圈装订的笔记本。把右页从中央对折，就可以藏起答案。另外，横线上印有均匀间隔小点的笔记本，用来作图会很方便。推荐。&lt;/p&gt;
&lt;p&gt;&lt;b&gt;译者注：&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;说到学习用笔记本。在日本学生族中，非常流行一种“&lt;b&gt;东大笔记本&lt;/b&gt;”。&lt;/p&gt;
&lt;p&gt;完整说来，是：&lt;b&gt;东京大学的学生经常使用的一种横线笔记本&lt;/b&gt;。这种笔记本最大的特点是横线上印有均匀小点。做笔记时划线、区分、间隔、作图十分方便，也整齐美观。&lt;/p&gt;
&lt;p&gt;这类笔记本虽然由于东大学生的普遍使用而名声大噪，但其实是早就存在于市面上的平民用品。下面图片中，左边那款Campus，中文名叫“国誉”的东大笔记本，是不是很熟悉？也许你也早就用过了呢。&lt;/p&gt;
&lt;p&gt;&lt;img border="0" alt="" src="http://photo.staticsdo.com/a1/366/273/195/83991-1453314369-8.jpg"&gt;&lt;/p&gt;
&lt;p&gt;（&lt;a href="http://www.bunshun.co.jp/toudai_note/practice/index.html"&gt;图片来源&lt;/a&gt;）&lt;/p&gt;
&lt;table cellspacing="0" cellpadding="3" border="0" style="clear:both"&gt;
    
    &lt;tr&gt;
        &lt;td colspan="4"&gt;&lt;b&gt;&lt;font size="-1" style="display:block!important;padding:20px 0 5px!important"&gt;您可能也喜欢：&lt;/font&gt;&lt;/b&gt;&lt;/td&gt;
    &lt;/tr&gt;
    
        &lt;tr&gt;
                &lt;td width="102" valign="top" style="padding:5px!important;margin:0!important"&gt;
                    &lt;a title="《Google时代的工作方法》读书笔记（2）纸质文档与电子文档的选择" style="text-decoration:none!important" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fwww.read.org.cn%2Fhtml%2F1648-paper-documents-and-electronic-document-choice.html&amp;amp;from=http%3A%2F%2Fwww.read.org.cn%2Fhtml%2F1666-you-pass-the-exam-will-prevail-notes-method.html"&gt;
                        &lt;img style="margin:0!important;padding:2px!important;border:1px solid #dddddd!important;width:96px!important;height:96px!important" src="http://static.wumii.com/site_images/2011/11/07/10393880.jpg" width="96px" height="96px"&gt;&lt;br&gt;
                        &lt;font size="-1" color="#333333" style="display:block!important;line-height:15px!important;width:102px!important;font:12px/15px arial!important;height:60px!important;margin:3px 0 0 0!important;padding:0!important;overflow:hidden!important"&gt;《Google时代的工作方法》读书笔记（2）纸质文档与电子文档的选择&lt;/font&gt;
                    &lt;/a&gt;
                &lt;/td&gt;
                &lt;td width="102" valign="top" style="padding:5px!important;margin:0!important;border-left:1px solid #dddddd!important"&gt;
                    &lt;a title="使用思维导图来帮助你快速学习和通过考试（2）" style="text-decoration:none!important" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fwww.read.org.cn%2Fhtml%2F544-use-mind-mapping-to-help-you-study-and-pass-the-exam-express-2.html&amp;amp;from=http%3A%2F%2Fwww.read.org.cn%2Fhtml%2F1666-you-pass-the-exam-will-prevail-notes-method.html"&gt;
                        &lt;img style="margin:0!important;padding:2px!important;border:1px solid #dddddd!important;width:96px!important;height:96px!important" src="http://static.wumii.com/images/blogWidget/wordpress_default.gif" width="96px" height="96px"&gt;&lt;br&gt;
                        &lt;font size="-1" color="#333333" style="display:block!important;line-height:15px!important;width:102px!important;font:12px/15px arial!important;height:60px!important;margin:3px 0 0 0!important;padding:0!important;overflow:hidden!important"&gt;使用思维导图来帮助你快速学习和通过考试（2）&lt;/font&gt;
                    &lt;/a&gt;
                &lt;/td&gt;
                &lt;td width="102" valign="top" style="padding:5px!important;margin:0!important;border-left:1px solid #dddddd!important"&gt;
                    &lt;a title="《两小时掌握学英语的秘诀》读书笔记－掌握书面英语" style="text-decoration:none!important" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fwww.read.org.cn%2Fhtml%2F81-two-hours-grasping-study-english-secret-grasps-the-written-english.html&amp;amp;from=http%3A%2F%2Fwww.read.org.cn%2Fhtml%2F1666-you-pass-the-exam-will-prevail-notes-method.html"&gt;
                        &lt;img style="margin:0!important;padding:2px!important;border:1px solid #dddddd!important;width:96px!important;height:96px!important" src="http://static.wumii.com/images/blogWidget/wordpress_default.gif" width="96px" height="96px"&gt;&lt;br&gt;
                        &lt;font size="-1" color="#333333" style="display:block!important;line-height:15px!important;width:102px!important;font:12px/15px arial!important;height:60px!important;margin:3px 0 0 0!important;padding:0!important;overflow:hidden!important"&gt;《两小时掌握学英语的秘诀》读书笔记－掌握书面英语&lt;/font&gt;
                    &lt;/a&gt;
                &lt;/td&gt;
                &lt;td width="102" valign="top" style="padding:5px!important;margin:0!important;border-left:1px solid #dddddd!important"&gt;
                    &lt;a title="在OneNote中使用康奈尔笔记系统来记笔记" style="text-decoration:none!important" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fwww.read.org.cn%2Fhtml%2F696-cornell-in-the-onenote-notebook-system-used-to-take-notes.html&amp;amp;from=http%3A%2F%2Fwww.read.org.cn%2Fhtml%2F1666-you-pass-the-exam-will-prevail-notes-method.html"&gt;
                        &lt;img style="margin:0!important;padding:2px!important;border:1px solid #dddddd!important;width:96px!important;height:96px!important" src="http://static.wumii.com/site_images/2011/06/18/12969326.png" width="96px" height="96px"&gt;&lt;br&gt;
                        &lt;font size="-1" color="#333333" style="display:block!important;line-height:15px!important;width:102px!important;font:12px/15px arial!important;height:60px!important;margin:3px 0 0 0!important;padding:0!important;overflow:hidden!important"&gt;在OneNote中使用康奈尔笔记系统来记笔记&lt;/font&gt;
                    &lt;/a&gt;
                &lt;/td&gt;
        &lt;/tr&gt;
    
    &lt;tr&gt;
        &lt;td colspan="4" align="right"&gt;
            &lt;a style="text-decoration:none!important" href="http://www.wumii.com/widget/relatedItems.htm" title="无觅相关文章插件"&gt;
                &lt;font size="-1" color="#bbbbbb" style="display:block!important;font-family:arial!important;padding:5px 0!important;font-size:12px!important;color:#bbb!important"&gt;无觅&lt;/font&gt;
            &lt;/a&gt;
        &lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;&lt;img src="http://www1.feedsky.com/t1/580010063/warfalcon/feedsky/s.gif?r=http://www.read.org.cn/html/1666-you-pass-the-exam-will-prevail-notes-method.html" border="0" height="0" width="0"&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>笔记 学习时间管理笔记 学习方法 时间管理 笔记本</category>
      <guid isPermaLink="true">https://itindex.net/detail/34191-%E8%80%83%E8%AF%95-%E7%AC%94%E8%AE%B0</guid>
      <pubDate>Thu, 24 Nov 2011 09:32:17 CST</pubDate>
    </item>
    <item>
      <title>[来自异次元] BooguNote – 碎片化信息收集与组织工具 (免费轻巧的树形笔记软件)</title>
      <link>https://itindex.net/detail/33907-%E6%AC%A1%E5%85%83-boogunote-%E7%A2%8E%E7%89%87%E5%8C%96</link>
      <description>&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Odj-s_EpGM5Mc-0gwqKPWCmjfB4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Odj-s_EpGM5Mc-0gwqKPWCmjfB4/0/di" border="0" ismap&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Odj-s_EpGM5Mc-0gwqKPWCmjfB4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Odj-s_EpGM5Mc-0gwqKPWCmjfB4/1/di" border="0" ismap&gt;&lt;/a&gt;&lt;/p&gt;&lt;div&gt;&lt;a href="http://www.iplaysoft.com/boogunote.html"&gt;&lt;img alt="BooguNote - 碎片化信息收集与组织工具 (免费轻巧的树形笔记软件)" src="http://img.iplaysoft.com/wp-content/uploads/2011/25fe54eba50d_A757/boogunote.jpg" border="0"&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;p&gt;&lt;p&gt;关于信息&lt;a href="http://www.iplaysoft.com/tag/%E6%94%B6%E9%9B%86"&gt;收集&lt;/a&gt;工具，异次元已经介绍过不少了，比方说 &lt;a href="http://www.iplaysoft.com/evernote.html"&gt;Evernote&lt;/a&gt;、&lt;a href="http://www.iplaysoft.com/wiz.html"&gt;Wiz&lt;/a&gt;、&lt;a href="http://www.iplaysoft.com/youdao-note.html"&gt;有道笔记&lt;/a&gt;、&lt;a href="http://www.iplaysoft.com/maiku.html"&gt;麦库&lt;/a&gt;、&lt;a href="http://www.iplaysoft.com/cintanotes.html"&gt;CintaNotes&lt;/a&gt; 等等。在信息收集方面这些工具已经很强大了。但今天介绍的和他们有些不同，它就是 &lt;a href="http://www.iplaysoft.com/boogunote.html"&gt;BooguNote&lt;/a&gt;——专注于碎片化信息收集与组织的工具。&lt;/p&gt;

&lt;p&gt;我们先来看看什么叫做碎片化信息。比方说：脑子里突然闪过一些好的点子；浏览&lt;a href="http://www.iplaysoft.com/tag/%E7%BD%91%E9%A1%B5"&gt;网页&lt;/a&gt;时偶遇的一个网址、一段文字、一张美图、一条微博；一个电话号码；一部电影或者书籍的名字；一条乘车路线。它们出现时候是杂乱无章的孤立的信息碎片。因为凌乱所以不好收集和组织，但往往它们却对你很重要。而 &lt;strong&gt;BooguNote&lt;/strong&gt; 就是未解决这一问题孕育而生的……&lt;/p&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.iplaysoft.com/boogunote.html"&gt;[  我要围观....  ]&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;div&gt;&lt;hr style="border:1px solid rgb(238, 238, 238);height:0pt"&gt;&lt;p&gt;&lt;strong style="color:rgb(255, 0, 0)"&gt;[ 异次元软件世界订阅地址 &lt;a title="异次元软件世界 RSS Feed" href="http://feed.iplaysoft.com"&gt;http://feed.iplaysoft.com&lt;/a&gt;  ]&lt;/strong&gt;&lt;/p&gt;&lt;a href="http://www.vancl.com/WebSource/WebSource.aspx?source=xforce&amp;amp;url=http://www.vancl.com/"&gt;&lt;img src="http://union.vancl.com/adpic.aspx?w=460&amp;amp;h=200" border="0"&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;异次元还有这些文章哟：&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.iplaysoft.com/stickies.html"&gt;Stickies - 免费且小巧精致的桌面便签条记事工具&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iplaysoft.com/xmind.html"&gt;XMind - 免费好用的开源思维导图制作编辑软件 (支持Windows/Mac/Linux)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iplaysoft.com/build-your-own-knowledge-system.html"&gt;建立你自己的知识管理系统：学习、保存、分享！&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iplaysoft.com/youdao-note.html"&gt;网易有道笔记 - 基于云端同步的多平台笔记文章资料整理收集软件&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iplaysoft.com/wunderlist.html"&gt;Wunderlist - 简洁雅致免费的跨平台网络云同步GTD工具 (Todo/记事/任务提醒/工作安排)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iplaysoft.com/evernote.html"&gt;EverNote 极致的免费笔记资料管理软件 (数据网络同步、支持PC、Mac与手机多平台)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iplaysoft.com/guang-su-sou-suo.html"&gt;光速搜索 - 小巧极速的桌面搜索小工具，瞬间找到一切需要的文件！&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;img src="http://img.tongji.linezing.com/1805014/tongji.gif"&gt;&lt;img src="http://www1.feedsky.com/t1/573765574/iplaysoft/feedsky/s.gif?r=http://www.iplaysoft.com/boogunote.html" border="0" height="0" width="0"&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>笔记 工作 记事 整理 维基</category>
      <guid isPermaLink="true">https://itindex.net/detail/33907-%E6%AC%A1%E5%85%83-boogunote-%E7%A2%8E%E7%89%87%E5%8C%96</guid>
      <pubDate>Mon, 07 Nov 2011 12:44:13 CST</pubDate>
    </item>
    <item>
      <title>《一日学习法》读书笔记-每天前进一厘米</title>
      <link>https://itindex.net/detail/34332-%E5%AD%A6%E4%B9%A0-%E8%AF%BB%E4%B9%A6-%E7%AC%94%E8%AE%B0</link>
      <description>&lt;p&gt;&lt;img border="0" src="http://img3.douban.com/lpic/s4489908.jpg"&gt; &lt;/p&gt;
&lt;p&gt;#每天一本书#2011年9月22日，279天,《一日学习法》，评分3分，一个韩国高考状员写的学习方法书籍，里面的技巧对于初、高中学生非常实用，有兴趣的可以看看。非常同意书中的这句话：保持每天进步一厘米的心态，成功在于积少成多。&lt;/p&gt;
&lt;p&gt;1、阅读让大脑变得更适合学习，坚持读书习惯，能改变人生，学烦可以通过看书放松。多样化读书，一本想读得，一本不想读，但是必须读得。&lt;/p&gt;
&lt;p&gt;2、提高成绩的笔记原则（提前预习；笔记尽量记在书上，准备好便利贴；划线时先画铅笔，第二次用圆珠笔，第三次用红笔，最后用荧光笔）&lt;/p&gt;
&lt;p&gt;3、摆脱低潮期的学习法：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;1）学习场所没有跟学习无关的东西，可以避免开小差。 &lt;/p&gt;
&lt;p&gt;2.）学习力不从心的时候，找备考手记和成功案例，去自己喜欢的大学看下，再不行就早点睡觉，低潮往往是因为疲劳。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;4、掌握要领，集中注意力 &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;1）、最大限度细化目标 &lt;/p&gt;
&lt;p&gt;2）、将截止时间定的短一些。 &lt;/p&gt;
&lt;p&gt;3）、把目录放在手边学习 &lt;/p&gt;
&lt;p&gt;4）、关闭手机或调静音 &lt;/p&gt;
&lt;p&gt;5）、尽量买最大的笔袋 &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;5、学会休息也有原则 &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;1)、警惕打盹（不要成习惯） &lt;/p&gt;
&lt;p&gt;2)、短时间的休息不是放松大脑，而是让身体得到休息（课间不要一直坐在座位上，看书久了不妨运动下） &lt;/p&gt;
&lt;p&gt;3)、一定要在学完之后再进行长时间的休息 &lt;/p&gt;
&lt;p&gt;4)、周日不学习&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;在因为同类的书看的比较多，类似的技巧以前就整理完了，记录下的技巧非常少，在豆瓣打分时，发现已经有豆友做了非常全面细致的记录，直接转载一下。&lt;/p&gt;
&lt;p&gt;转自：&lt;a href="http://book.douban.com/review/5040254/"&gt;http://book.douban.com/review/5040254/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;作者：传奇&lt;/p&gt;
&lt;p&gt; &lt;font color="#0000ff"&gt;在你对平凡的生活感到厌倦的时候，你也可以改变过去的自己。只要你对某件事情充满热情、积极努力，你就拥有了实现自身价值的机会。我们该苦恼的事情只有一个，那就是如何将“一天”这个时间过得更充实。所有变化都从与别人不同的“一天”开始，是从努力学习的充实的“一天”开始。&lt;br&gt;
    &lt;br&gt;这里小结一下那些我认为非常可行的方法： &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;&lt;font color="#ff8000"&gt;第一章：一日学习的秘密 &lt;/font&gt;&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第一：学习的第一步就是早睡。&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;每天保证七个小时的睡眠时间。最晚不能超过晚上十一点。 &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第二：起床以后、去学校之前，至少要进行30分钟的“晨间学习”。不要把这个建议当成耳旁风，一定要切实地实践一下。 &lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;1、每天早起至少半个小时，起床洗漱完毕后做一些计算题，让头脑转动起来。 &lt;/p&gt;
&lt;p&gt;2、 等大脑慢慢运转起来之后，就开始学一些平常觉得困难的东西。至于要学什么科目，可以根据自己情况不同进行调节。 &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;第三：将学习效率提高2倍的预习方法。&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;1、预习不是提前学习。更接近于一种对将要学习内容的“确认”。 &lt;/p&gt;
&lt;p&gt;2、预习的工具就是“真题”。 &lt;/p&gt;
&lt;p&gt;真题里的内容都还没有学过，看也做不出来。不过，不是为了做题才去看真题的。看真题是为了了解今天要学的部分中，哪些是重要内容，哪些会在考试中出现。那老师上课讲那个部分的时候，就可以更集中精神去听。那样，上课时就不会只是被动地听讲，而是积极弥补自身的不足。 &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第四：活用课堂时间的诀窍。&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;1、往前坐。 &lt;/p&gt;
&lt;p&gt;2、不要看书，要看老师的眼睛。为了防止开小差，可以迅速重复老师说过的话（就像许三多那样，哈哈）即便上课时不理解也不要放弃。 &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;1）、拼命跟紧上课的进度才是快速提高成绩的秘诀。 &lt;/p&gt;
&lt;p&gt;2）、上课的时间一定要专注于课堂，学习中的不足另外再找时间补充。 &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;4、如果你是上游水平的学生，那就打开各种教材，拓展一下学习范围。 &lt;/p&gt;
&lt;p&gt;同时参考多本教材，能填补老师上课没有讲到、直接跳过的部分。采取这种积极的态度去听课一定会非常累。但是，认为老师讲的内容自己都会就抱着胳膊听课的上游生，和参考各种教材、努力为自己查缺补漏听课的上游生，谁会一跃成为最优秀的学生，恐怕就不言自明了。 &lt;/p&gt;
&lt;p&gt;5、改变对待老师的态度发现每一位老师的优点，让自己喜欢上他，这是不偏课的保证。 &lt;/p&gt;
&lt;p&gt;6、课上大声回答老师的问题这是保证自己注意力集中的好办法提高成绩的笔记原则：所谓的笔记不是听写，而是查补自身不足的过程。 &lt;/p&gt;
&lt;p&gt;7、如果想提高记笔记的效率，那一定要切实地作好预习。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A、只有预习了，才知道老师现在讲的内容是单纯地重复教材上的内容，还是在进行附加说明。哪怕只是预习很短的时间再去上课，笔记的量也会大幅减少。因为预习了之后，是以有疑问的地方为主来做笔记，所以上课的时候注意力会更集中，也有了思考的时间。虽然笔记的量减少了很多，但是成绩反而快速提高了。 &lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;B、还有一点值得大家参考，那就是大部分的内容教科书和参考书里都有，不要另外准备笔记本。 &lt;/p&gt;
&lt;p&gt;C、听课的时候，碰到需要记笔记的地方，不必写在笔记本上，而是写在教材的空白处。 &lt;/p&gt;
&lt;p&gt;D、在教材上做笔记一定要准备好便利贴。 &lt;/p&gt;
&lt;p&gt;在教材的空白处做笔记，经常会碰到空间不够的情况，那时你可以把笔记的内容写在便利贴上，然后再贴在教材上。写错了可以重写，等以后上面的内容都变成自己的知识后还可以揭下来，教材又恢复整洁了。 &lt;/p&gt;
&lt;p&gt;E、画下划线的时候最好是多准备几种画线用的笔，随着次数的增加更换不同的笔。 &lt;/p&gt;
&lt;p&gt;预习时先用铅笔画线，（结合预习和真题你认为重要的部分）。 &lt;/p&gt;
&lt;p&gt;听讲时用圆珠笔，（上课时老师反复强调的部分）。 &lt;/p&gt;
&lt;p&gt;老师讲重点部分用红色笔，（复习时老师强调的部分）。 &lt;/p&gt;
&lt;p&gt;复习时用荧光笔，（总复习时的重点部分）。 &lt;/p&gt;
&lt;p&gt;F、只要看一下教材和笔记本就能知道一个学生的成绩。上课用的书上一点儿标记都没有、整本书都干干净净的，那那个学生一定处于下游。与之相反，如果书上仔仔细细密密麻麻地写着笔记，那这本书一定不是最上游学生的，而是中上游学生的书。笔记做得这么详细，上课时肯定注意力不集中。上游学生的书里只是简简单单地写下了必须要记下来的内容，简单明了地用自己的语言把平时的疑问和老师强调的内容记下来。 &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;第五：每晚写学习日志（包括：学习量，难点等）&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;&lt;font color="#ff8000"&gt;第二章：迅速提高综合成绩的秘诀&lt;/font&gt;&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;第一：选定教材的三种策略&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;1、是对要学的内容进行限定：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;1)只挑选重要的一两本重复看，是考好综合考试的秘诀。 &lt;/p&gt;
&lt;p&gt;2)、将主教材与辅助教材分离。所谓主教材指的是教科书和老师分发的学习资料，是最重要的教材，这些教材要反复看。为了自学买的综合考试备考习题集、辅导班里整理出来的教材等，原则上是把它们当做参考书来使用。 &lt;/p&gt;
&lt;p&gt;3)、不要看新教材。 &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;第二：最棒的综合考试备考日程表&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;1、考试前两周再开始复习，这两周的课程以课堂听讲为主，不再算入复习时间。 &lt;/p&gt;
&lt;p&gt;2、按照课程表严格复习。 &lt;/p&gt;
&lt;p&gt;3、下课之后的自习时间要为当天所学的科目作考试准备。不是复习课堂上的内容，而是学习整个科目。 &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;第三：组织学习小组共同学习。 &lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;&lt;font color="#ff8000"&gt;第三章：假期高效学习的原则&lt;/font&gt;&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;原则1：高成绩不是靠预习，而是靠复习首先要限定必须攻克的科目。最好集中学习数学和英语。 &lt;/p&gt;
&lt;p&gt;原则2：量减少家中生活，在公共图书馆度过假期。家是最差的学习地点，因为紧张的感觉全都释放掉了。 &lt;/p&gt;
&lt;p&gt;原则3：技巧地制订假期学习计划、制订的计划绝对不要勉强，这是制订计划时最重要的原则。坚持写学习日志。 &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;1、不要制订具体时间表。只要把一天的时间三等分，分成早中晚就足够了。 &lt;/p&gt;
&lt;p&gt;2、为计划搁置作好准备。在周末另外确定一个时间补上落下的学习内容。 &lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;strong&gt;&lt;font color="#ff8000"&gt;第四章：快速摆脱低潮期的方法&lt;/font&gt;&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;方法1：定近期的具体目标&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;举例：作者在数学只考了25分时下决心要好好学习的那一天，他做的第一件事情就是准备练习本、圆珠笔、尺子和刀。他先在纸上写下“进入全校前50名”的目标，然后剪下来后用胶带粘在书桌和练习本的第一页上。在任何人看来这都是个盲目的目标，但不知道为什么，每一次只要他看到那个目标，就会燃起学习的热情。 &lt;/p&gt;
&lt;p&gt;学习就是与低潮较量的过程，而低潮是可以通过努力克服的。 &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;方法2：查学习场所的气氛&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;检视自己学习场所的氛围、把书桌整理得干干净净是防止低潮期的最简单、最行之有效的方法。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;转载本站文件请保留原始链接。&lt;/p&gt;
&lt;p&gt;我现在经常在微博上出现，欢迎大家利用微博和豆瓣来提问，我尽量找时间来回复，如果没有马上回复是因为时间关系，请耐心等待一下。&lt;/p&gt;
&lt;p&gt;如果你觉得我分享的东西不错，请关注我：&lt;strong&gt;1、&lt;a href="http://weibo.com/warfalcon"&gt;新浪&lt;/a&gt; 2、&lt;a href="http://www.douban.com/people/warfalcon/"&gt;豆瓣&lt;/a&gt; 3、&lt;a href="http://t.qq.com/warfalcon"&gt;腾迅&lt;/a&gt; 4、&lt;/strong&gt;&lt;a href="http://www.twitter.com/warfalcon"&gt;Twitter&lt;/a&gt; 5、&lt;a href="http://www.zhihu.com/people/warfalcon"&gt;知乎&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;如果你对思维导图感兴趣，可以看看我的另一个Blog，&lt;a href="http://www.write.org.cn/"&gt;http://www.write.org.cn&lt;/a&gt; 已经提供了100本图书的思维导图源文件下载，欢迎访问和定阅。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;读书笔记：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;RSS地址： &lt;a href="http://feed.write.org.cn/"&gt;http://feed.write.org.cn&lt;/a&gt;  Web: &lt;a href="http://www.write.org.cn/"&gt;http://www.write.org.cn&lt;/a&gt; QQ邮箱请点击&lt;a href="http://mail.qq.com/cgi-bin/bookcol?colid=20039"&gt;&lt;img border="0" alt="订阅到QQ邮箱" src="http://rescdn.qqmail.com/zh_CN/dy/btn_dyrss.gif"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;战隼的学习探索：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;RSS地址： &lt;a href="http://feed.read.org.cn/"&gt;http://feed.read.org.cn&lt;/a&gt;  Web: &lt;a href="http://www.read.org.cn/"&gt;http://www.read.org.cn&lt;/a&gt; QQ邮箱请点击 &lt;img border="0" alt="订阅到QQ邮箱" src="http://rescdn.qqmail.com/zh_CN/dy/btn_dyrss.gif"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img border="0" src="http://www1.feedsky.com/t1/577241790/warfalcon/feedsky/s.gif?r=http%3A//www.read.org.cn/html/1654-how-effective-application-mind-mapping-and-role-embodies.html" width="0" height="0"&gt;&lt;/p&gt;
&lt;table cellspacing="0" cellpadding="3" border="0" style="clear:both"&gt;
    
    &lt;tr&gt;
        &lt;td colspan="4"&gt;&lt;b&gt;&lt;font size="-1" style="display:block!important;padding:20px 0 5px!important"&gt;您可能也喜欢：&lt;/font&gt;&lt;/b&gt;&lt;/td&gt;
    &lt;/tr&gt;
    
        &lt;tr&gt;
                &lt;td width="102" valign="top" style="padding:5px!important;margin:0!important"&gt;
                    &lt;a title="考试过关必胜笔记法" style="text-decoration:none!important" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fwww.read.org.cn%2Fhtml%2F1666-you-pass-the-exam-will-prevail-notes-method.html&amp;amp;from=http%3A%2F%2Fwww.read.org.cn%2Fhtml%2F1677-one-day-study-note.html"&gt;
                        &lt;img style="margin:0!important;padding:2px!important;border:1px solid #dddddd!important;width:96px!important;height:96px!important" src="http://static.wumii.com/site_images/2011/11/24/11384915.jpg" width="96px" height="96px"&gt;&lt;br&gt;
                        &lt;font size="-1" color="#333333" style="display:block!important;line-height:15px!important;width:102px!important;font:12px/15px arial!important;height:60px!important;margin:3px 0 0 0!important;padding:0!important;overflow:hidden!important"&gt;考试过关必胜笔记法&lt;/font&gt;
                    &lt;/a&gt;
                &lt;/td&gt;
                &lt;td width="102" valign="top" style="padding:5px!important;margin:0!important;border-left:1px solid #dddddd!important"&gt;
                    &lt;a title="六色荧光笔学习法（１）" style="text-decoration:none!important" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fwww.read.org.cn%2Fhtml%2F2008%2F03%2F21%2Fsix-color-fluorogenic-pen-study-the-law%2F&amp;amp;from=http%3A%2F%2Fwww.read.org.cn%2Fhtml%2F1677-one-day-study-note.html"&gt;
                        &lt;img style="margin:0!important;padding:2px!important;border:1px solid #dddddd!important;width:96px!important;height:96px!important" src="http://static.wumii.com/images/blogWidget/wordpress_default.gif" width="96px" height="96px"&gt;&lt;br&gt;
                        &lt;font size="-1" color="#333333" style="display:block!important;line-height:15px!important;width:102px!important;font:12px/15px arial!important;height:60px!important;margin:3px 0 0 0!important;padding:0!important;overflow:hidden!important"&gt;六色荧光笔学习法（１）&lt;/font&gt;
                    &lt;/a&gt;
                &lt;/td&gt;
                &lt;td width="102" valign="top" style="padding:5px!important;margin:0!important;border-left:1px solid #dddddd!important"&gt;
                    &lt;a title="[ 转贴]学习时集中注意力的方法" style="text-decoration:none!important" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fwww.read.org.cn%2Fhtml%2F2007%2F08%2F17%2Fstudy-focused-approach%2F&amp;amp;from=http%3A%2F%2Fwww.read.org.cn%2Fhtml%2F1677-one-day-study-note.html"&gt;
                        &lt;img style="margin:0!important;padding:2px!important;border:1px solid #dddddd!important;width:96px!important;height:96px!important" src="http://static.wumii.com/images/blogWidget/wordpress_default.gif" width="96px" height="96px"&gt;&lt;br&gt;
                        &lt;font size="-1" color="#333333" style="display:block!important;line-height:15px!important;width:102px!important;font:12px/15px arial!important;height:60px!important;margin:3px 0 0 0!important;padding:0!important;overflow:hidden!important"&gt;[ 转贴]学习时集中注意力的方法&lt;/font&gt;
                    &lt;/a&gt;
                &lt;/td&gt;
                &lt;td width="102" valign="top" style="padding:5px!important;margin:0!important;border-left:1px solid #dddddd!important"&gt;
                    &lt;a title="《精力管理》读书笔记-1" style="text-decoration:none!important" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fwww.read.org.cn%2Fhtml%2F1181-energy-management-note-1.html&amp;amp;from=http%3A%2F%2Fwww.read.org.cn%2Fhtml%2F1677-one-day-study-note.html"&gt;
                        &lt;img style="margin:0!important;padding:2px!important;border:1px solid #dddddd!important;width:96px!important;height:96px!important" src="http://static.wumii.com/site_images/2011/02/28/2989649.jpg" width="96px" height="96px"&gt;&lt;br&gt;
                        &lt;font size="-1" color="#333333" style="display:block!important;line-height:15px!important;width:102px!important;font:12px/15px arial!important;height:60px!important;margin:3px 0 0 0!important;padding:0!important;overflow:hidden!important"&gt;《精力管理》读书笔记-1&lt;/font&gt;
                    &lt;/a&gt;
                &lt;/td&gt;
        &lt;/tr&gt;
        &lt;td&gt;&lt;br&gt;
    &lt;tr&gt;
        &lt;td colspan="4"&gt;&lt;b&gt;&lt;font size="-1" style="display:block!important;padding:20px 0 5px!important"&gt;来自无觅网络的相关文章：&lt;/font&gt;&lt;/b&gt;&lt;/td&gt;
    &lt;/tr&gt;
    
        &lt;tr&gt;
                &lt;td width="102" valign="top" style="padding:5px!important;margin:0!important"&gt;
                    &lt;a title="《一日学习法》思维导图读书笔记" style="text-decoration:none!important" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fwww.write.org.cn%2Flearning-day-mind-map-reading-notes.html&amp;amp;from=http%3A%2F%2Fwww.read.org.cn%2Fhtml%2F1677-one-day-study-note.html"&gt;
                        &lt;img style="margin:0!important;padding:2px!important;border:1px solid #dddddd!important;width:96px!important;height:96px!important" src="http://static.wumii.com/site_images/2011/09/25/33911467.jpg" width="96px" height="96px"&gt;&lt;br&gt;
                        &lt;font size="-1" color="#333333" style="display:block!important;line-height:15px!important;width:102px!important;font:12px/15px arial!important;height:60px!important;margin:3px 0 0 0!important;padding:0!important;overflow:hidden!important"&gt;《一日学习法》思维导图读书笔记 (@write)&lt;/font&gt;
                    &lt;/a&gt;
                &lt;/td&gt;
                &lt;td width="102" valign="top" style="padding:5px!important;margin:0!important;border-left:1px solid #dddddd!important"&gt;
                    &lt;a title="知识管理：高质量的信息源和高效的学习" style="text-decoration:none!important" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fwww.yixieshi.com%2Fzhichang%2F6464.html&amp;amp;from=http%3A%2F%2Fwww.read.org.cn%2Fhtml%2F1677-one-day-study-note.html"&gt;
                        &lt;img style="margin:0!important;padding:2px!important;border:1px solid #dddddd!important;width:96px!important;height:96px!important" src="http://static.wumii.com/site_images/2011/03/30/4586848.jpg" width="96px" height="96px"&gt;&lt;br&gt;
                        &lt;font size="-1" color="#333333" style="display:block!important;line-height:15px!important;width:102px!important;font:12px/15px arial!important;height:60px!important;margin:3px 0 0 0!important;padding:0!important;overflow:hidden!important"&gt;知识管理：高质量的信息源和高效的学习 (@yixieshi)&lt;/font&gt;
                    &lt;/a&gt;
                &lt;/td&gt;
                &lt;td width="102" valign="top" style="padding:5px!important;margin:0!important;border-left:1px solid #dddddd!important"&gt;
                    &lt;a title="《小强升职记》思维导图读书笔记（2）" style="text-decoration:none!important" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fwww.write.org.cn%2Fxiao-qiang-promotion-in-mind-mind-mapping-study-notes-2.html&amp;amp;from=http%3A%2F%2Fwww.read.org.cn%2Fhtml%2F1677-one-day-study-note.html"&gt;
                        &lt;img style="margin:0!important;padding:2px!important;border:1px solid #dddddd!important;width:96px!important;height:96px!important" src="http://static.wumii.com/site_images/2011/05/04/7538601.jpg" width="96px" height="96px"&gt;&lt;br&gt;
                        &lt;font size="-1" color="#333333" style="display:block!important;line-height:15px!important;width:102px!important;font:12px/15px arial!important;height:60px!important;margin:3px 0 0 0!important;padding:0!important;overflow:hidden!important"&gt;《小强升职记》思维导图读书笔记（2） (@write)&lt;/font&gt;
                    &lt;/a&gt;
                &lt;/td&gt;
                &lt;td width="102" valign="top" style="padding:5px!important;margin:0!important;border-left:1px solid #dddddd!important"&gt;
                    &lt;a title="吴谈如《时间管理幸福学》思维导图读书笔记分享" style="text-decoration:none!important" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fwww.write.org.cn%2Fwu-talks-such-as-time-management-science-of-happiness-to-share-mind-map-reading-notes.html&amp;amp;from=http%3A%2F%2Fwww.read.org.cn%2Fhtml%2F1677-one-day-study-note.html"&gt;
                        &lt;img style="margin:0!important;padding:2px!important;border:1px solid #dddddd!important;width:96px!important;height:96px!important" src="http://static.wumii.com/site_images/2011/08/18/23382636.jpg" width="96px" height="96px"&gt;&lt;br&gt;
                        &lt;font size="-1" color="#333333" style="display:block!important;line-height:15px!important;width:102px!important;font:12px/15px arial!important;height:60px!important;margin:3px 0 0 0!important;padding:0!important;overflow:hidden!important"&gt;吴谈如《时间管理幸福学》思维导图读书笔记分享 (@write)&lt;/font&gt;
                    &lt;/a&gt;
                &lt;/td&gt;
        &lt;/tr&gt;
    
    &lt;tr&gt;
        &lt;td colspan="4" align="right"&gt;
            &lt;a style="text-decoration:none!important" href="http://www.wumii.com/widget/relatedItems.htm" title="无觅相关文章插件"&gt;
                &lt;font size="-1" color="#bbbbbb" style="display:block!important;font-family:arial!important;padding:5px 0!important;font-size:12px!important;color:#bbb!important"&gt;无觅&lt;/font&gt;
            &lt;/a&gt;
        &lt;/td&gt;
    &lt;/tr&gt;
&lt;/td&gt;&lt;/table&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>笔记 学习方法 一日学习法 时间管理 每天前进一厘米</category>
      <guid isPermaLink="true">https://itindex.net/detail/34332-%E5%AD%A6%E4%B9%A0-%E8%AF%BB%E4%B9%A6-%E7%AC%94%E8%AE%B0</guid>
      <pubDate>Thu, 01 Dec 2011 08:54:57 CST</pubDate>
    </item>
  </channel>
</rss>

