<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tony Bai &#187; cloud-native</title>
	<atom:link href="http://tonybai.com/tag/cloud-native/feed/" rel="self" type="application/rss+xml" />
	<link>https://tonybai.com</link>
	<description>一个程序员的心路历程</description>
	<lastBuildDate>Wed, 08 Apr 2026 00:17:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>体验Gemini Deep Research：以Go语言未来演进方向分析为例</title>
		<link>https://tonybai.com/2025/03/16/gemini-deep-research-experience/</link>
		<comments>https://tonybai.com/2025/03/16/gemini-deep-research-experience/#comments</comments>
		<pubDate>Sun, 16 Mar 2025 07:10:54 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[adoption]]></category>
		<category><![CDATA[Agent]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[AI/ML]]></category>
		<category><![CDATA[analysis]]></category>
		<category><![CDATA[backend]]></category>
		<category><![CDATA[bytes]]></category>
		<category><![CDATA[challenges]]></category>
		<category><![CDATA[channels]]></category>
		<category><![CDATA[cloud-native]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[compatibility]]></category>
		<category><![CDATA[competition]]></category>
		<category><![CDATA[Concurrency]]></category>
		<category><![CDATA[containers]]></category>
		<category><![CDATA[dataprocessing]]></category>
		<category><![CDATA[DeepResearch]]></category>
		<category><![CDATA[deepseek]]></category>
		<category><![CDATA[dependencies]]></category>
		<category><![CDATA[developers]]></category>
		<category><![CDATA[digitalillustration]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[ecosystem]]></category>
		<category><![CDATA[edgecomputing]]></category>
		<category><![CDATA[efficiency]]></category>
		<category><![CDATA[ErrorHandling]]></category>
		<category><![CDATA[feedback]]></category>
		<category><![CDATA[FIPS140-3]]></category>
		<category><![CDATA[gemini]]></category>
		<category><![CDATA[Gemini1.5Pro]]></category>
		<category><![CDATA[GeminiDeepResearch]]></category>
		<category><![CDATA[generics]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[go.mod]]></category>
		<category><![CDATA[go1.24]]></category>
		<category><![CDATA[go:wasmexport]]></category>
		<category><![CDATA[GoCommand]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[GoModules]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Gopher]]></category>
		<category><![CDATA[goroutines]]></category>
		<category><![CDATA[govet]]></category>
		<category><![CDATA[IDEintegration]]></category>
		<category><![CDATA[infrastructure]]></category>
		<category><![CDATA[insights]]></category>
		<category><![CDATA[Iot]]></category>
		<category><![CDATA[iterators]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[LLM]]></category>
		<category><![CDATA[machinelearning]]></category>
		<category><![CDATA[maps]]></category>
		<category><![CDATA[math/rand/v2]]></category>
		<category><![CDATA[memoryallocation]]></category>
		<category><![CDATA[Microservices]]></category>
		<category><![CDATA[ML]]></category>
		<category><![CDATA[modeldeployment]]></category>
		<category><![CDATA[Mutex]]></category>
		<category><![CDATA[neuralnetworks]]></category>
		<category><![CDATA[Opensource]]></category>
		<category><![CDATA[os.Root]]></category>
		<category><![CDATA[packagemanagement]]></category>
		<category><![CDATA[parallelism]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[programminglanguage]]></category>
		<category><![CDATA[proposals]]></category>
		<category><![CDATA[report]]></category>
		<category><![CDATA[research]]></category>
		<category><![CDATA[runtime]]></category>
		<category><![CDATA[runtime.AddCleanup]]></category>
		<category><![CDATA[RussCox]]></category>
		<category><![CDATA[Rust]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[simplicity]]></category>
		<category><![CDATA[standardlibrary]]></category>
		<category><![CDATA[strings]]></category>
		<category><![CDATA[survey]]></category>
		<category><![CDATA[SwissTables]]></category>
		<category><![CDATA[testing/synctest]]></category>
		<category><![CDATA[trends]]></category>
		<category><![CDATA[typealiases]]></category>
		<category><![CDATA[wasi]]></category>
		<category><![CDATA[wasm]]></category>
		<category><![CDATA[WebAssembly]]></category>
		<category><![CDATA[人工智能]]></category>
		<category><![CDATA[大模型]]></category>
		<category><![CDATA[深度思考]]></category>
		<category><![CDATA[谷歌]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=4513</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2025/03/16/gemini-deep-research-experience 基于大模型的AI已进入深度思考时代，以DeepSeek R1模型为代表的开源模型给主流AI厂商带来了巨大压力。其实早在2024年12月份，Google就在一篇名为“Try Deep Research and our new experimental model in Gemini, your AI assistant”中发布了自己的Deep Research产品：Gemini Deep Research。 Gemini Deep Research不仅仅是一个简单的搜索引擎，而是一个智能研究助理。用户只需输入研究主题，Deep Research即可自动完成以下工作： 自动制定研究计划：根据主题的复杂性，Deep Research会生成一个多步骤的研究计划。 深度网络信息分析：Deep Research会像人类研究员一样，在网络上进行多轮搜索、分析、筛选，并根据已获取的信息不断调整搜索策略。 生成综合报告：最终，Deep Research会生成一份结构化的报告，包含关键发现、主要观点以及原始资料链接。 支持交互式提问：用户可以对报告内容进行追问，Deep Research会进一步解释或补充信息。 不过最初发布时，免费用户体验受到了限制。2025.3.13 Google更新了其AI产品gemini的功能特性，并宣布在Gemini 2.0 Flash Thinking等模型上增加Deep Research功能(并且相对于早期的功能又有了能力上的增强)。现在即便你是免费用户，只要打开Gemini应用的主页面，就能看到下面带有Deep Research功能选项的对话输入框： 并且，在Gemini app页面上免费用户可以使用的模型都支持Deep Research，虽然每月依然有使用次数限制： 作为Gemini AI助手的一项重要特性，基于大窗口增强后的Deep Research利用Gogle强大的信息搜索能力以及AI强大的信息处理能力，可为用户提供深度、全面的研究报告，大幅提高了研究效率。 在信息爆炸的时代，我们这些技术人员面临着持续学习和快速掌握新技术、新趋势的巨大挑战。传统的研究方法往往耗时费力，如何在海量信息中高效提取关键信息，已成为提升技术竞争力的关键要素。 本文将以”Go语言未来5-10年的演进方向及核心团队发力重点”这一主题为例，分享我对增强版Gemini Deep Research的抢先体验。 实战体验：Go语言未来演进方向研究 为了测试Deep Research的实际效果，我选择了一个对Go开发者非常关心的话题： “Go语言未来5-10年的演进方向以及Go核心团队的发力重点会在哪里？” 研究过程 启动研究 [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/gemini-deep-research-experience-1.png" alt="" /></p>
<p><a href="https://tonybai.com/2025/03/16/gemini-deep-research-experience">本文永久链接</a> &#8211; https://tonybai.com/2025/03/16/gemini-deep-research-experience</p>
<p>基于大模型的AI已进入深度思考时代，以DeepSeek R1模型为代表的开源模型给主流AI厂商带来了巨大压力。其实早在2024年12月份，Google就在一篇名为“<a href="https://blog.google/products/gemini/google-gemini-deep-research/">Try Deep Research and our new experimental model in Gemini, your AI assistant</a>”中发布了自己的Deep Research产品：<a href="https://blog.google/products/gemini/google-gemini-deep-research/">Gemini Deep Research</a>。</p>
<p>Gemini Deep Research不仅仅是一个简单的搜索引擎，而是一个智能研究助理。用户只需输入研究主题，Deep Research即可自动完成以下工作：</p>
<ul>
<li><strong>自动制定研究计划</strong>：根据主题的复杂性，Deep Research会生成一个<strong>多步骤</strong>的研究计划。</li>
<li><strong>深度网络信息分析</strong>：Deep Research会像人类研究员一样，在网络上进行多轮搜索、分析、筛选，并根据已获取的信息不断调整搜索策略。</li>
<li><strong>生成综合报告</strong>：最终，Deep Research会生成一份结构化的报告，包含关键发现、主要观点以及原始资料链接。</li>
<li><strong>支持交互式提问</strong>：用户可以对报告内容进行追问，Deep Research会进一步解释或补充信息。</li>
</ul>
<p>不过最初发布时，免费用户体验受到了限制。<a href="https://blog.google/products/gemini/new-gemini-app-features-march-2025/">2025.3.13 Google更新了其AI产品gemini的功能特性</a>，并宣布在Gemini 2.0 Flash Thinking等模型上增加Deep Research功能(并且相对于早期的功能又有了能力上的增强)。现在即便你是免费用户，只要打开Gemini应用的主页面，就能看到下面带有Deep Research功能选项的对话输入框：</p>
<p><img src="https://tonybai.com/wp-content/uploads/gemini-deep-research-experience-2.png" alt="" /></p>
<p>并且，在<a href="https://gemini.google.com/app">Gemini app页面</a>上免费用户可以使用的模型都支持Deep Research，虽然每月依然有使用次数限制：</p>
<p><img src="https://tonybai.com/wp-content/uploads/gemini-deep-research-experience-3.png" alt="" /></p>
<p>作为Gemini AI助手的一项重要特性，基于大窗口增强后的Deep Research利用Gogle强大的信息搜索能力以及AI强大的信息处理能力，可为用户提供深度、全面的研究报告，大幅提高了研究效率。</p>
<p>在信息爆炸的时代，我们这些技术人员面临着持续学习和快速掌握新技术、新趋势的巨大挑战。传统的研究方法往往耗时费力，如何在海量信息中高效提取关键信息，已成为提升技术竞争力的关键要素。</p>
<p>本文将以”Go语言未来5-10年的演进方向及核心团队发力重点”这一主题为例，分享我对增强版Gemini Deep Research的抢先体验。</p>
<h2>实战体验：Go语言未来演进方向研究</h2>
<p>为了测试Deep Research的实际效果，我选择了一个对Go开发者非常关心的话题：</p>
<blockquote>
<p>“Go语言未来5-10年的演进方向以及Go核心团队的发力重点会在哪里？”</p>
</blockquote>
<h3>研究过程</h3>
<h4><strong>启动研究</strong></h4>
<p>在Gemini对话框中输入上述主题，并在左上角选择”Deep Research”模型，然后提交。</p>
<p>Gemini会首先会自动生成研究计划，如下图，并等待你的确认：</p>
<p><img src="https://tonybai.com/wp-content/uploads/gemini-deep-research-experience-4.png" alt="" /></p>
<h4><strong>确认方案，并等待研究完成</strong></h4>
<p>你可以修改方案，也可以点击“开始研究”，一旦选择后者，Deep Research就会自动开始进行研究(包括反复的数据搜索、分析结果等)。在研究过程中，Gemini会显示当前的研究进度，例如”正在分析相关信息”、”正在生成报告”等，下面是研究过程的一些截图：</p>
<p><img src="https://tonybai.com/wp-content/uploads/gemini-deep-research-experience-5.png" alt="" /><br />
<img src="https://tonybai.com/wp-content/uploads/gemini-deep-research-experience-6.png" alt="" /><br />
<img src="https://tonybai.com/wp-content/uploads/gemini-deep-research-experience-7.png" alt="" /><br />
<img src="https://tonybai.com/wp-content/uploads/gemini-deep-research-experience-8.png" alt="" /><br />
<img src="https://tonybai.com/wp-content/uploads/gemini-deep-research-experience-9.png" alt="" /><br />
&#8230; &#8230;<br />
<img src="https://tonybai.com/wp-content/uploads/gemini-deep-research-experience-10.png" alt="" /></p>
<p>整个过程大约持续了10-15分钟（具体时间取决于主题的复杂性）。</p>
<h4><strong>获取研究报告</strong></h4>
<p>研究完成后，Gemini生成了一份详细的报告，结构完整，内容丰富。Gemini支持将报告导出到Google Doc，之后你便可以基于Google Doc查看、编辑或下载这份研究报告了。Gemini为我生成的这份报告放在了<a href="https://docs.google.com/document/d/1xFjbaVUqaJhge_PXRkeVwzeiVStrXTuUBBrNvzhwjxI/edit">这里</a>。如果你访问不了，我在本文附录也放了一份报告结果，请参考。</p>
<p>下面我们再简单看一下报告质量。</p>
<h3>研究报告内容与质量分析</h3>
<p>这次Gemini针对我提出的题目生成的报告包含以下主要章节：</p>
<ul>
<li>Go语言的持久相关性与未来轨迹</li>
<li>近期重要进展分析（Go 1.24及未来）</li>
<li>核心团队的优先事项解读：解读发力重点</li>
<li>未来5-10年Go语言的演进方向</li>
<li>Go的应用：应对现代挑战</li>
<li>Go未来面临的挑战和考虑因素</li>
<li>结论：规划Go未来十年的发展方向</li>
<li>相关统计表格和参考文献</li>
</ul>
<p>从全面性来看，该报告涵盖了Go语言发展的多个维度，从技术细节（如泛型、性能优化、WebAssembly支持）到宏观趋势（如云计算、边缘计算、AI/ML集成），再到社区和生态系统的发展，内容全面而不失重点。</p>
<p>该报告不仅是信息的简单堆砌，而是对信息进行了深入的分析和整合，不乏一定的<strong>深度</strong>。例如，报告准确地指出了Go核心团队在性能优化、并发、WebAssembly等方面的持续投入，并分析了这些投入背后的战略意图。</p>
<p>报告还给出了引用的信息的确切来源，包括Go官方博客、技术文章、社区讨论等，初步看了一眼，信息来源相关性强，且地址可靠。比如：报告中提到的Go 1.24的新特性、核心团队的优先事项等，都与官方信息保持一致。</p>
<p>报告也提出了一些有价值的洞察，例如Go在边缘计算和物联网领域的潜力、在AI/ML领域可能的发展方向等，为读者提供了前瞻性的视角。</p>
<p>报告结构非常清晰，语言流畅，易于理解。即使是对Go语言不太熟悉的读者，也能通过报告快速了解Go语言的未来发展趋势。</p>
<p>该报告的撰写质量估计已经超过了许多有多年Go开发经验的资深工程师所能提供的分析。如果一个技术人员亲自去调研和总结这些内容，没有3-5天的时间投入是很难完成的。</p>
<h2>体验结论</h2>
<p>通过此次体验，我们可以深刻地感受到Gemini Deep Research的强大功能和巨大潜力：</p>
<ul>
<li><strong>效率提升</strong>：Deep Research将原本需要数小时甚至数天的研究工作缩短至几分钟，极大地提高了研究效率。</li>
<li><strong>信息全面性</strong>：Deep Research能够从多个来源获取信息，并进行综合分析，避免了人工研究可能存在的遗漏和偏见。</li>
<li><strong>深度洞察</strong>：Deep Research不仅是信息的搬运工，它能够对信息进行深入分析，提炼出有价值的洞察。</li>
<li><strong>持续学习</strong>：Deep Research处于不断进化中，未来将会变得越来越强大。</li>
</ul>
<p>Gemini Deep Research等深度研究工具的出现与演进，标志着AI驱动的研究新时代的到来。它将改变我们获取信息、分析信息、利用信息的方式，为各行各业带来巨大的变革。对于技术团队来说，Deep Research无疑是一个强大的工具，可以帮助我们更快地学习、更深入地思考、更高效地工作。</p>
<h2>附录</h2>
<h3><strong>Go语言未来5-10年的演进方向及核心团队发力重点</strong></h3>
<p><strong>1&#46; 引言：Go的持久相关性与未来轨迹</strong></p>
<p>自2009年公开宣布，并于2012年发布1.0版本以来，Go语言已在现代软件开发领域占据重要地位，尤其是在云基础设施和可扩展系统方面 1。其设计初衷是为了解决大规模软件开发的复杂性 6，强调简洁、高效和并发性 1。Go语言的用户群体显著增长，表明其采用率和相关性不断提高 10。这种增长凸显了理解其未来演进以及Go核心团队优先事项的必要性。本报告将分析近期发展、社区讨论以及Go项目关键人物的见解，以预测未来5到10年Go语言的发展轨迹，重点关注核心团队的努力方向。</p>
<p>Go语言最初的创建动机是为了解决Google在软件基础设施方面面临的实际问题，例如C++在构建现代服务器软件时遇到的构建缓慢、依赖管理失控和并发编程困难等挑战 1。这种以解决实际问题为导向的设计思路深深植根于Go语言的基因中，可以预见，未来Go核心团队将继续关注实际应用，并致力于满足开发人员的需求。</p>
<p>Go语言用户群体的持续增长以及主要科技公司的广泛采用，为Go语言的未来发展奠定了坚实的基础 10。来自各种调查的数据一致显示，越来越多的开发人员正在使用Go语言，并且有学习Go语言的意愿。诸如Google、Netflix、Uber和Dropbox等公司 3 在其关键基础设施中对Go语言的依赖，突显了Go语言的成熟性和适用于大规模项目的能力，这无疑将确保核心团队和社区对Go语言的持续投入和发展。</p>
<p><strong>2&#46; 近期重要进展分析：Go 1.24及未来</strong></p>
<p>2025年2月发布的Go 1.24版本是一个重要的里程碑，它揭示了Go核心团队当前的优先事项 17。此版本的主要特性包括：</p>
<ul>
<li>完全支持泛型类型别名，增强了代码的灵活性并减少了冗余 17。这解决了社区长期以来的一个需求 8。  </li>
<li>运行时性能得到提升，在一系列代表性基准测试中，CPU开销平均降低了2-3%。这些改进包括基于Swiss Tables的新map实现、更高效的小对象内存分配以及新的内部互斥锁实现 10。  </li>
<li>通过go:wasmexport指令将Go函数导出到Wasm，并支持构建为WASI反应器/库，增强了WebAssembly (Wasm) 的功能 17。这标志着Go语言正日益关注将其应用范围扩展到传统的服务器端应用之外 21。  </li>
<li>go.mod中新增了管理工具依赖的机制 18，并且go vet命令通过新的测试分析器得到了改进 18。这些变化旨在改善开发人员的体验和代码质量。  </li>
<li>标准库新增了FIPS 140-3合规性机制、用于目录限制文件系统访问的新os.Root类型以及比runtime.SetFinalizer更灵活的runtime.AddCleanup函数用于清理操作 1。这些新增功能增强了Go在安全性、系统编程和资源管理方面的能力。  </li>
<li>用于测试并发代码的实验性testing/synctest包 17。这突显了并发性在Go语言发展中的持续重要性。  </li>
<li>bytes和strings包中新增了基于迭代器的新函数，提高了常见数据处理任务的效率 18。</li>
</ul>
<p>Go 1.24中包含的诸如泛型等长期以来备受期待的功能，体现了核心团队对社区反馈的积极响应以及他们为满足现代编程需求而不断发展语言的意愿。Go社区对泛型的需求由来已久 8。Go 1.18开始引入泛型，并在1.24版本中进一步完善了对泛型类型别名的支持，这表明核心团队认真听取了开发者的意见，并准备在社区达成广泛共识且对生态系统有明显益处时，对语言进行重大改变。</p>
<p>Go 1.24中显著的性能改进，进一步巩固了Go语言在效率和速度方面的核心价值主张，预示着性能优化将继续成为核心团队未来的重点工作。关于使用Swiss Tables加速Go map以及其他运行时改进的详细博客文章 10 清晰地表明，核心团队正在持续努力使Go程序在现代硬件上运行得更快、更高效。这与Go最初为基础设施软件设定的设计目标相一致。</p>
<p>Go 1.24中对WebAssembly功能的增强，暗示着Go语言正在战略性地定位自己，使其成为一种能够在包括Web浏览器和基于云的Wasm运行时等多种环境中运行的多功能语言。go:wasmexport指令和WASI反应器支持的引入 17 不仅仅是增量式的变化，它们代表着核心团队有意使Go成为更具吸引力的WebAssembly开发选择。关于可扩展Wasm应用的博客文章 17 详细介绍了这些新增功能，表明核心团队期望Go在浏览器端和服务器端的Wasm应用中都发挥重要作用。</p>
<p><strong>3&#46; 核心团队的优先事项：解读发力重点</strong></p>
<p>基于近期发布的版本、Go团队的博客文章 10 以及社区讨论，可以识别出Go核心团队的几个关键优先事项：</p>
<ul>
<li><strong>持续强调性能和效率：</strong> 每个版本中持续的性能改进 10 表明，保持和提升Go的性能特性仍然是首要任务。这包括针对现代硬件优化运行时、标准库和编译器 10。对诸如新的map实现和内存分配改进等底层优化的关注，表明核心团队致力于从根本上提高Go的性能，从而使广泛的应用受益。关于Swiss Tables的博客文章 17 详细介绍了这些深层次的运行时修改，表明了对核心性能的长期投入。  </li>
<li><strong>并发和并行方面的进步：</strong> Go在并发方面的优势 1 仍然是关键的关注点，实验性testing/synctest包的引入 17 表明，核心团队正在不断努力改进并发编程的工具和支持。关于未来可能增强并发模型的讨论 25 也表明了其持续的重要性。开发专门用于测试并发代码的工具（如实验性的testing/synctest包 17）突显了核心团队致力于确保并发Go程序的可靠性和正确性，这对于许多目标用例（如云基础设施和分布式系统）至关重要。并发是Go语言的一个核心差异化优势，而对更好的测试框架的投入则体现了对其健壮性的承诺。介绍testing/synctest的博客文章 17 证实了这一重点。  </li>
<li><strong>对WebAssembly能力的战略投资：</strong> Go 1.24中对Wasm支持的显著增强 17 以及社区持续的兴趣 21 表明，使Go成为一种可行的WebAssembly语言是核心团队的战略重点。这为Go在前端开发和其他基于Wasm的环境中开辟了新的可能性 18。通过go:wasmexport将Go函数导出到Wasm宿主，并构建WASI反应器的双重关注，表明了核心团队对Wasm支持采取了全面的方法，旨在实现与各种Wasm生态系统（包括浏览器和服务器端环境）的互操作性。关于可扩展Wasm应用的博客文章 17 详细介绍了这种双重方法，表明核心团队设想Go在浏览器端和服务器端的Wasm应用中都将发挥重要作用。  </li>
<li><strong>加强语言和标准库的安全性：</strong> Go 1.24中包含的FIPS 140-3合规性机制 17 以及Go生态系统中关于安全性的持续讨论 8 突显了核心团队致力于使Go成为构建关键应用的安全语言。对内存安全的关注 1 也与这一优先事项相符。通过简单的环境变量 18 提供对FIPS认证加密的内置支持，体现了核心团队对安全性的积极态度，使得开发人员更容易构建符合安全规范的应用，而无需依赖外部库或复杂的配置。此功能直接解决了软件开发中日益增长的安全性重要性，尤其适用于需要遵守FIPS标准的企业和政府应用。  </li>
<li><strong>持续优化云原生架构：</strong> Go在云原生开发领域的强大影响力 2 是显而易见的，预计核心团队将继续为该领域优化语言和标准库。这包括与微服务、容器化 9 以及与云平台的集成 38 相关的改进。Docker和Kubernetes等主要的云基础设施工具都是用Go语言构建的 9，这使得Go的未来与云原生技术的演进紧密相连。这表明核心团队可能会优先考虑那些能够使该生态系统中的开发人员受益的功能和改进。Go在云生态系统中的基础性作用为核心团队提供了强大的动力，以确保它仍然非常适合这些工作负载，并保持其在该领域相对于其他语言的竞争优势。  </li>
<li><strong>探索Go在新兴领域的潜力（AI/ML，边缘计算）：</strong> 尽管Go在AI/ML领域尚未占据主导地位 8，但在该领域的使用潜力正在增长，尤其是在部署模型和构建基础设施方面 10。同样，Go的高效性和小巧的体积使其成为边缘计算和IoT应用的有力候选者 8。核心团队对支持这些领域的努力可能会在未来增加，正如关于Go在AI系统中的作用的讨论所表明的那样 10。Go在处理大型数据集方面的高效率及其在高性能AI应用开发方面的潜力 8 表明，即使Go的目标不是取代Python成为主要的模型开发语言，核心团队也可能正在探索增强Go在某些AI/ML工作负载（如高性能推理或构建AI基础设施）方面的适用性的方法。Go的性能优势可以在速度和效率至关重要的AI/ML领域（如推理或边缘部署，其中低延迟至关重要）得到利用。Go的轻量级特性和内置的并发性 26 与边缘计算和IoT的需求非常契合，在这些环境中，资源受限和需要处理大量并发连接是很常见的。这种天然的契合性表明核心团队可能会继续优化Go以适应这些环境。  </li>
<li><strong>提升开发者体验：工具和生态系统：</strong> 核心团队始终致力于通过增强工具 8（包括go命令、go vet和IDE集成 38）来改善开发者体验。错误处理 8 和包管理 5 的改进也是持续的优先事项。Go生态系统的健康发展 8 对于语言未来的成功至关重要。Go 1.24中引入的用于管理工具依赖的工具（使用go get &#45;tool和go tool 18）直接解决了Go开发人员常见的workflow挑战，简化了开发所需的外部实用程序的管理，体现了对实用性和改善Go程序员日常体验的关注。简化开发工具的依赖管理可以改善整体开发者体验，并减少Go项目中的摩擦。诸如go vet（带有新的测试分析器）等现有工具的持续改进以及对新工具和功能的不断探索 8 表明，核心团队致力于为Go程序员提供一个健壮高效的开发环境，帮助他们编写更好更可靠的代码。强大的工具链对于开发者生产力至关重要，核心团队对这方面的投入反映了其对于Go语言长期成功的意义。</li>
</ul>
<p><strong>4&#46; 不断演进的格局：未来5-10年的Go语言</strong></p>
<p>展望未来，可以预见Go语言的几个趋势和潜在发展方向：</p>
<ul>
<li><strong>预期的语言演进和潜在的新特性：</strong> 尽管Go 1.x一直秉持着对向后兼容性的坚定承诺 1，但泛型的引入 8 表明，Go愿意为了解决关键的局限性和满足社区的需求而进行演进。未来的演进可能包括进一步完善泛型、潜在地改进错误处理 8，以及基于社区反馈和不断发展的技术格局，谨慎地引入其他特性。关于“Go 2.0”的讨论 8 表明了对更重大变革的长期愿景，但核心团队强调将采取循序渐进的方式 35。正如Russ Cox 48 所阐述的，以及Go语言缓慢但稳步的发展历程 35 所反映的那样，核心团队对语言的改变采取谨慎的态度。这表明，虽然核心团队对演进持开放态度，但他们将继续优先考虑稳定性和向后兼容性，以避免破坏庞大的现有Go代码生态系统。这种谨慎的做法一直是Go语言发展的标志，并且很可能会继续下去，从而确保Go语言对于长期项目来说仍然是一个可靠的选择。  </li>
<li><strong>标准库的增长和成熟：</strong> 标准库是Go语言的一大优势 1，提供了广泛的开箱即用功能。预计未来的增长将包括新的包以及对现有包的改进，可能涉及网络、数据处理和对新兴技术的支持等领域。math/rand/v2包的引入 10 为未来的库演进和现代化提供了一个范例。正如Go语言15周年纪念 10 中提到的那样，引入带有版本控制的新标准库包（如math/rand/v2）表明了一种具有前瞻性的库演进方法。这使得在不破坏与旧版本兼容性的情况下实现重大改进和新功能成为可能，为在遵守Go 1兼容性承诺的同时实现现代化提供了一条途径。  </li>
<li><strong>Go Modules和依赖管理的作用：</strong> Go Modules 5 已成为Go语言依赖管理的标准，未来的发展可能会侧重于进一步简化和增强该系统。go.mod中工具指令的引入 18 是这种演进的最新例证。对Go Modules的持续改进，例如跟踪工具依赖的能力 18，表明核心团队致力于提供一个健壮且用户友好的依赖管理系统。这对于大型复杂的Go项目的可扩展性和可维护性至关重要，并反映了持续改进开发者体验的努力。  </li>
<li><strong>社区影响和开源贡献：</strong> Go的开源特性 1 意味着社区通过提案 49、贡献和反馈 16 在其发展中发挥着重要作用。核心团队通过调查 17 和讨论积极与社区互动，使得社区的意见成为塑造Go未来发展方向的关键因素。提案流程本身 56 确保了任何重大变更在被采纳之前都会在社区内得到仔细考虑和讨论。Go开发者调查 17 是核心团队收集广泛反馈并了解Go社区的使用模式、挑战和期望改进的关键机制。这种数据驱动的方法确保了语言的演进能够满足用户的实际需求。</li>
</ul>
<p><strong>5&#46; Go的应用：应对现代挑战</strong></p>
<p>Go语言的设计和近期发展使其能够很好地应对软件开发中的几个现代挑战：</p>
<ul>
<li><strong>云计算和微服务：巩固Go的地位：</strong> Go的高效性、并发性和小巧的二进制文件使其非常适合构建云原生应用和微服务 3。其持续的演进，包括性能的提升和并发测试工具的改进，可能会进一步加强其在该领域的地位。Go语言通过goroutine和channel实现的内置并发模型 1 为构建需要高效处理大量并发请求的分布式系统和微服务提供了显著的优势。与依赖外部库实现并发的语言相比，这种内置的并发模型简化了可扩展和响应迅速的云应用的开发。  </li>
<li><strong>边缘计算和物联网：发挥Go的效率优势：</strong> Go的性能和较小的资源占用使其成为边缘计算和物联网应用的绝佳选择 8。随着这些领域的持续增长，Go的作用预计将进一步扩大，尤其是在针对资源受限环境进行优化方面。Go语言生成的小巧且自包含的二进制文件 1 对于资源受限（如内存和处理能力）的边缘设备和物联网环境尤其有益。这使得Go应用能够在更广泛的硬件上高效运行。  </li>
<li><strong>WebAssembly：将Go的触角延伸到前端：</strong> 凭借Go 1.24中增强的Wasm支持和持续的开发 17，Go正成为构建高性能前端Web应用的可行选择，可能在某些领域挑战JavaScript的主导地位，尤其是在计算密集型任务或需要浏览器中实现类似原生性能的应用方面。即使编译为WebAssembly 24，Go的性能特性也为Web应用带来了相比传统基于JavaScript的解决方案的显著性能提升潜力，尤其是在涉及复杂计算或需要与系统资源紧密交互的应用方面。  </li>
<li><strong>人工智能和机器学习：探索新的领域：</strong> 尽管在库的可用性方面仍然存在挑战 15，但Go的性能和效率使其成为部署和提供AI/ML模型的有希望的语言 8。未来的发展可能会看到对基于Go的AI/ML库和框架的更多投入，可能侧重于Go的优势（如用于并行处理的并发性）特别有益的领域。Go强大的性能和并发能力使其非常适合构建支持AI/ML工作负载的基础设施，例如数据处理管道、模型服务平台和分布式训练系统，即使它不会成为所有AI/ML开发阶段的主要语言。</li>
</ul>
<p><strong>6&#46; Go未来面临的挑战和考虑因素</strong></p>
<p>尽管Go语言的发展前景良好，但也面临着一些挑战和需要考虑的因素：</p>
<ul>
<li><strong>在简洁性与特性扩展之间取得平衡：</strong> Go的简洁性是其核心优势之一 1，但诸如泛型等特性的加入也引入了复杂性。核心团队必须在对新特性的渴望与保持语言的简洁性和可读性之间仔细权衡 8。泛型的引入虽然解决了社区的一个主要需求，但也代表着Go最初极简主义设计理念的一次偏离。核心团队需要继续仔细评估未来的特性提案，以确保它们在提供实质性好处的同时，不会过度损害语言的可读性和易于理解的核心原则。  </li>
<li><strong>回应社区反馈和不断变化的需求：</strong> Go社区对某些限制和期望的特性提出了很多意见 8，核心团队需要继续与这些反馈互动，并在坚守其核心原则的同时，使语言适应不断变化的需求 10。核心团队通过调查、博客文章和提案流程 17 与Go社区的积极互动对于确保语言的演进符合用户的实际需求和更广泛的软件开发趋势至关重要。维持这种开放的沟通和反馈循环对于Go语言的长期健康和相关性至关重要。  </li>
<li><strong>来自其他编程语言的竞争：</strong> Go面临着来自其他现代编程语言（如Rust 5）以及其他也针对类似领域（如云原生开发和高性能计算）的语言的竞争。Go未来的成功将取决于其维持独特优势并继续响应竞争格局而发展自身的能力。尽管Go和Rust经常在相似的领域展开竞争，但它们提供了不同的权衡（例如，Go的简洁性与Rust对不使用垃圾回收的内存安全的关注）。Go的持续成功可能取决于强调其优势并解决其相对于竞争对手的劣势，例如错误处理的冗长 59 或其他语言中存在的某些高级语言特性的缺乏。</li>
</ul>
<p><strong>7&#46; 结论：规划Go未来十年的发展方向</strong></p>
<p>Go语言有望在未来5到10年内继续保持增长和发展。正如近期发布的版本和社区互动所表明的那样，核心团队的优先事项侧重于持续的性能改进、并发方面的进步、对WebAssembly的战略投资、加强安全性、持续优化云原生架构以及探索AI/ML和边缘计算等新兴领域。</p>
<p>尽管在简洁性与特性扩展之间取得平衡以及应对竞争格局将是关键的挑战，但Go语言强大的基础、活跃的社区以及核心团队致力于满足开发者需求的承诺，都预示着Go语言拥有光明的未来。其适应现代挑战的能力以及对实用解决方案的持续关注，可能会在未来几年内巩固其作为构建可靠、可扩展和高效软件系统的关键语言的地位。</p>
<p><strong>有价值的表格：</strong></p>
<ol>
<li><strong>表格：近期Go版本（Go 1.23和Go 1.24）的关键特性和关注领域</strong></li>
</ol>
<table>
<thead>
<tr>
<th align="left">版本</th>
<th align="left">关键语言特性</th>
<th align="left">显著性能提升</th>
<th align="left">工具增强</th>
<th align="left">标准库新增/变更</th>
<th align="left">版本体现的关注领域</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">Go 1.23</td>
<td align="left">slices/maps中的迭代器函数</td>
<td align="left">配置文件引导优化 (PGO)</td>
<td align="left">改进的go命令</td>
<td align="left">新增iter包</td>
<td align="left">性能，泛型集成</td>
</tr>
<tr>
<td align="left">Go 1.24</td>
<td align="left">泛型类型别名</td>
<td align="left">更快的map (Swiss Tables), 内存分配, 互斥锁</td>
<td align="left">新的测试分析器，工具依赖管理</td>
<td align="left">FIPS 140-3, os.Root, runtime.AddCleanup, 弱指针</td>
<td align="left">性能，泛型，Wasm，安全，开发者体验</td>
</tr>
</tbody>
</table>
<ol>
<li><strong>表格：Go语言的采用统计数据和趋势</strong></li>
</ol>
<table>
<thead>
<tr>
<th align="left">年份</th>
<th align="left">统计来源</th>
<th align="left">指标</th>
<th align="left">主要发现/趋势</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">2024</td>
<td align="left">Stack Overflow 开发者调查</td>
<td align="left">最受喜爱的编程语言之一</td>
<td align="left">表明开发者满意度高。</td>
</tr>
<tr>
<td align="left">2024</td>
<td align="left">Talent.com</td>
<td align="left">美国Go开发者平均年薪约为$132,823</td>
<td align="left">显示出对Go开发者的强烈需求和高价值。</td>
</tr>
<tr>
<td align="left">2023</td>
<td align="left">Go开发者调查 H2</td>
<td align="left">&#62;90% 开发者满意度</td>
<td align="left">突显了Go社区内的积极体验。</td>
</tr>
<tr>
<td align="left">2021</td>
<td align="left">Stack Overflow 调查</td>
<td align="left">约9.55% 的开发者使用Go</td>
<td align="left">显示出相当一部分开发者正在积极使用Go。</td>
</tr>
<tr>
<td align="left">2020</td>
<td align="left">JetBrains 开发者生态系统</td>
<td align="left">约110万主要Go开发者，约270万包括第二语言</td>
<td align="left">表明全球拥有庞大且不断增长的Go开发者社区。</td>
</tr>
<tr>
<td align="left">2019</td>
<td align="left">Stack Overflow 调查</td>
<td align="left">Go是第三大最想学习的语言</td>
<td align="left">表明随着更多开发者希望获得Go技能，其采用率将持续增长。</td>
</tr>
<tr>
<td align="left">2024</td>
<td align="left">Okoone.com</td>
<td align="left">Go的用户群在过去五年内增长了两倍</td>
<td align="left">表明Go的受欢迎程度和采用率迅速增长。</td>
</tr>
<tr>
<td align="left">2024</td>
<td align="left">Developer Nation 调查</td>
<td align="left">11% 的后端开发者目前使用Go</td>
<td align="left">提供了Go在关键目标人群中的具体采用率。</td>
</tr>
</tbody>
</table>
<p><strong>Works cited</strong></p>
<p>// 数量太多，这里省略。</p>
<hr />
<p><a href="https://public.zsxq.com/groups/51284458844544">Gopher部落知识星球</a>在2025年将继续致力于打造一个高品质的Go语言学习和交流平台。我们将继续提供优质的Go技术文章首发和阅读体验。并且，2025年将在星球首发“Go陷阱与缺陷”和“Go原理课”专栏！此外，我们还会加强星友之间的交流和互动。欢迎大家踊跃提问，分享心得，讨论技术。我会在第一时间进行解答和交流。我衷心希望Gopher部落可以成为大家学习、进步、交流的港湾。让我相聚在Gopher部落，享受coding的快乐! 欢迎大家踊跃加入！</p>
<p><img src="http://image.tonybai.com/img/tonybai/gopher-tribe-zsxq-small-card.png" alt="img{512x368}" /><br />
<img src="http://image.tonybai.com/img/tonybai/go-programming-from-beginner-to-master-qr.png" alt="img{512x368}" /></p>
<p><img src="http://image.tonybai.com/img/tonybai/go-first-course-banner.png" alt="img{512x368}" /><br />
<img src="http://image.tonybai.com/img/tonybai/imooc-go-column-pgo-with-qr.jpg" alt="img{512x368}" /></p>
<p>著名云主机服务厂商DigitalOcean发布最新的主机计划，入门级Droplet配置升级为：1 core CPU、1G内存、25G高速SSD，价格6$/月。有使用DigitalOcean需求的朋友，可以打开这个<a href="https://m.do.co/c/bff6eed92687">链接地址</a>：https://m.do.co/c/bff6eed92687 开启你的DO主机之路。</p>
<p>Gopher Daily(Gopher每日新闻) &#8211; https://gopherdaily.tonybai.com</p>
<p>我的联系方式：</p>
<ul>
<li>微博(暂不可用)：https://weibo.com/bigwhite20xx</li>
<li>微博2：https://weibo.com/u/6484441286</li>
<li>博客：tonybai.com</li>
<li>github: https://github.com/bigwhite</li>
<li>Gopher Daily归档 &#8211; https://github.com/bigwhite/gopherdaily</li>
<li>Gopher Daily Feed订阅 &#8211; https://gopherdaily.tonybai.com/feed</li>
</ul>
<p><img src="http://image.tonybai.com/img/tonybai/iamtonybai-wechat-qr.png" alt="" /></p>
<p>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。</p>
<p style='text-align:left'>&copy; 2025, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2025/03/16/gemini-deep-research-experience/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Go官方发布的go.dev给gopher们带来了什么</title>
		<link>https://tonybai.com/2019/11/14/what-the-godev-website-bring-to-gophers/</link>
		<comments>https://tonybai.com/2019/11/14/what-the-godev-website-bring-to-gophers/#comments</comments>
		<pubDate>Thu, 14 Nov 2019 02:44:42 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[cloud-native]]></category>
		<category><![CDATA[CNCF]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[go-nuts]]></category>
		<category><![CDATA[go-tour]]></category>
		<category><![CDATA[go.dev]]></category>
		<category><![CDATA[gobridge]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[GOPATH]]></category>
		<category><![CDATA[Gopher]]></category>
		<category><![CDATA[GopherCon]]></category>
		<category><![CDATA[hello-world]]></category>
		<category><![CDATA[logrus]]></category>
		<category><![CDATA[Package]]></category>
		<category><![CDATA[SRE]]></category>
		<category><![CDATA[tgpl]]></category>
		<category><![CDATA[云原生]]></category>
		<category><![CDATA[包]]></category>
		<category><![CDATA[命令行]]></category>
		<category><![CDATA[地鼠]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=2824</guid>
		<description><![CDATA[众所周知，Go是一个诞生于Google内部的编程语言，它在2009年11月份开源，在开源后立即受到了来自全世界开发人员的关注与贡献。但初期的Go语言的发展依旧是由Go核心团队的若干leader决定的，这种类“民主集中制”的方法延续了若干年。直到Go核心团队逐渐意识到Go应该更多倾听社区的声音，并让更多的gopher参与到Go项目的开发和贡献中来，甚至影响和决定一些语言特定的演化。于是Go团队开始特意为Go社区发展招兵买马。像Steve Francia、Francesc Campoy（后已经从google离职加入Dgraph）等都是在这个阶段加入Go team的。 Go团队在很长一段时间里尤其重视与社区的互动，比如连续多年发起Go user调查、Gophercon大会后的Go team与社区的见面会和分组讨论、去GOPATH降低Go入门学习曲线、发布Go新品牌标识、添加Go module机制、改善官网等。 在今天Go官博发文：“Go.dev: a new hub for Go developers”，正式发布go.dev站点，该站点被Go核心团队寄望于成为全世界Gopher开发人员的中心。它将告诉gopher（无论新手还是老油条）：谁在使用Go、用Go做什么、怎么学习Go(Go的各种学习资源、受欢迎的Go package都有哪些以及这些package的详细信息）。 go.dev发布之后，golang.org官网将更加聚焦go开源项目本身的开发、语言演化以及Go版本发布。而go.dev将成为gopher日常使用go语言的中心，包括go学习、go方案、go应用案例等。在这里我们简单探索一下go.dev这个站点究竟给gopher们带来了什么(这仅仅是go.dev的最小功能发布，后续go.dev可能会演化出更多特性、并根据社区反馈更好满足gopher需求)。 一. 学习资源聚合 go.dev的一个重要功能就是帮助首次进入Go世界的开发人员学习Go。 在go.dev的”learn”栏目下，我们在第一屏就看到了Go新手入门的三个步骤：安装、”Hello World”、Go tour以及更为详尽文档的入口： 接下来，go.dev提供了这些年口碑较好、受到gopher欢迎的一些初级在线学习资源： 像gobyexample.com、gophercises.com都在推荐行列。 Go技术类书籍以及培训资源是gopher学习Go过程中不可缺少的： Go.dev在learn栏目下推荐了一些口碑不错的Go书籍，比如：Alan A. A. Donovan和Brian W. Kernighan合著的Go圣经：《The Go Programming Language》被在首位推荐。知名Go培训师William Kennedy的培训也被推荐给了大家。不过口碑不错的书籍《Go in action》我觉得也应该列入推荐行列。 在Learn栏目最后，是全世界各地近期有关Go的meetup活动的schedule，Gopher可以得到最及时的meetup信息，并选择参加。 二. 成熟解决方案参考 go.dev开辟的”solution”栏目旨在提升go的开发过程。栏目从“云原生和网络服务开发”、“命令行程序开发”、“web开发”以及Devops/Site Reliability四个方面提供聚合化的资料。以“云原生和网络服务开发”为例，Go.dev提供了这方面的典型项目和用户、使用方法、关键方案（一些书籍、成熟框架、客户端库以及其他资源）。 go.dev solution栏目还提供了一些Go的典型客户以及这些客户使用Go的典型案例： 三、Package信息聚合中心 在go.dev的“explore”栏目下，我们看到的是Go package的信息中心： 就如上图所示，这里提供了受欢迎的package和特色package的推荐列表，以及package信息的搜索功能。 以logrus为例： 在logrus包的主页，我们看到了有关logrus的各种信息，项目repo地址、最新版本号、module名字、开源许可证信息、文档（应该是集成了godoc返回的结果）、它的依赖、以及以它为依赖的项目(见下图)： 四. 小结 go.dev目前处于最小产品状态(mvp)，从目前已经提供的栏目来看，go.dev能为gopher提供的帮助已经很全面了。后续go.dev站点的运营好坏（比如：信息更新是否及时等）将决定go.dev是否能达到其预期的期望。 go.dev目前似乎还缺少论坛功能。不过已有的golang-nuts、gobridge已经承担了这个角色，但如果能有一个官方论坛（一站式）就再好不过了。 [...]]]></description>
			<content:encoded><![CDATA[<p>众所周知，<a href="https://tonybai.com/2017/09/24/go-ten-years-and-climbing/">Go是一个诞生于Google内部的编程语言</a>，它在<a href="https://tonybai.com/2019/11/09/go-opensource-10-years/">2009年11月份开源</a>，在开源后立即受到了来自全世界开发人员的关注与贡献。但初期的Go语言的发展依旧是由Go核心团队的若干leader决定的，这种类“民主集中制”的方法延续了若干年。直到Go核心团队逐渐意识到Go应该更多倾听社区的声音，并让更多的gopher参与到Go项目的开发和贡献中来，甚至影响和决定一些语言特定的演化。于是Go团队开始特意为Go社区发展<strong>招兵买马</strong>。像<a href="https://spf13.com/">Steve Francia</a>、<a href="https://campoy.cat/">Francesc Campoy</a>（后已经从google离职加入<a href="https://dgraph.io/">Dgraph</a>）等都是在这个阶段加入Go team的。</p>
<p>Go团队在很长一段时间里尤其重视与社区的互动，比如连续多年发起<a href="https://blog.golang.org/survey2018-results">Go user调查</a>、<a href="https://www.gophercon.com/">Gophercon大会</a>后的Go team<a href="https://blog.golang.org/contributor-workshop">与社区的见面会和分组讨论</a>、<a href="https://tip.golang.org/doc/go1.8#gopath">去GOPATH降低Go入门学习曲线</a>、<a href="https://blog.golang.org/go-brand">发布Go新品牌标识</a>、添加<a href="https://tonybai.com/2018/11/19/some-changes-in-go-1-11/">Go module机制</a>、<a href="https://golang.org/">改善官网</a>等。</p>
<p>在今天Go官博发文：<a href="https://blog.golang.org/go.dev">“Go.dev: a new hub for Go developers”</a>，正式发布<a href="https://go.dev/">go.dev站点</a>，该站点被Go核心团队寄望于成为全世界Gopher开发人员的中心。它将告诉gopher（无论新手还是老油条）：谁在使用Go、用Go做什么、怎么学习Go(Go的各种学习资源、受欢迎的Go package都有哪些以及这些package的详细信息）。</p>
<p><img src="https://tonybai.com/wp-content/uploads/go.dev/homepage.png" alt="img{512x368}" /></p>
<p>go.dev发布之后，golang.org官网将更加聚焦go开源项目本身的开发、语言演化以及Go版本发布。而go.dev将成为gopher日常使用go语言的中心，包括go学习、go方案、go应用案例等。在这里我们简单探索一下go.dev这个站点究竟给gopher们带来了什么(这仅仅是go.dev的最小功能发布，后续go.dev可能会演化出更多特性、并根据社区反馈更好满足gopher需求)。</p>
<h2>一. <a href="https://learn.go.dev/">学习资源</a>聚合</h2>
<p>go.dev的一个重要功能就是<strong>帮助首次进入Go世界的开发人员学习Go</strong>。</p>
<p>在go.dev的”learn”栏目下，我们在第一屏就看到了Go新手入门的三个步骤：安装、”Hello World”、Go tour以及<a href="https://golang.org/doc/">更为详尽文档的入口</a>：</p>
<p><img src="https://tonybai.com/wp-content/uploads/go.dev/learn-1.png" alt="img{512x368}" /></p>
<p>接下来，go.dev提供了这些年口碑较好、受到gopher欢迎的一些初级在线学习资源：</p>
<p><img src="https://tonybai.com/wp-content/uploads/go.dev/learn-2.png" alt="img{512x368}" /></p>
<p>像gobyexample.com、gophercises.com都在推荐行列。</p>
<p>Go技术类书籍以及培训资源是gopher学习Go过程中不可缺少的：</p>
<p><img src="https://tonybai.com/wp-content/uploads/go.dev/learn-3.png" alt="img{512x368}" /></p>
<p>Go.dev在learn栏目下推荐了一些口碑不错的Go书籍，比如：Alan A. A. Donovan和<a href="https://www.cs.princeton.edu/~bwk/">Brian W. Kernighan</a>合著的<a href="http://www.gopl.io/">Go圣经：《The Go Programming Language》</a>被在首位推荐。知名Go培训师William Kennedy的<a href="https://www.ardanlabs.com/">培训</a>也被推荐给了大家。不过口碑不错的书籍<a href="https://book.douban.com/subject/25858023/">《Go in action》</a>我觉得也应该列入推荐行列。</p>
<p>在Learn栏目最后，是全世界各地近期有关Go的meetup活动的schedule，Gopher可以得到最及时的meetup信息，并选择参加。</p>
<h2>二. 成熟解决方案参考</h2>
<p><img src="https://tonybai.com/wp-content/uploads/go.dev/solution-1.png" alt="img{512x368}" /></p>
<p>go.dev开辟的”solution”栏目旨在提升go的开发过程。栏目从“云原生和网络服务开发”、“命令行程序开发”、“web开发”以及Devops/Site Reliability四个方面提供聚合化的资料。以“云原生和网络服务开发”为例，Go.dev提供了这方面的典型项目和用户、使用方法、关键方案（一些书籍、成熟框架、客户端库以及其他资源）。</p>
<p>go.dev solution栏目还提供了一些Go的典型客户以及这些客户使用Go的典型案例：</p>
<p><img src="https://tonybai.com/wp-content/uploads/go.dev/solution-2.png" alt="img{512x368}" /></p>
<h2>三、Package信息聚合中心</h2>
<p>在go.dev的“explore”栏目下，我们看到的是Go package的信息中心：</p>
<p><img src="https://tonybai.com/wp-content/uploads/go.dev/explore-1.png" alt="img{512x368}" /></p>
<p>就如上图所示，这里提供了受欢迎的package和特色package的推荐列表，以及package信息的搜索功能。</p>
<p>以<a href="https://tonybai.com/2018/01/13/the-problems-i-encountered-when-writing-go-code-issue-1st/">logrus为例</a>：</p>
<p><img src="https://tonybai.com/wp-content/uploads/go.dev/explore-2.png" alt="img{512x368}" /></p>
<p>在<a href="https://github.com/sirupsen/logrus">logrus包</a>的主页，我们看到了有关logrus的各种信息，项目repo地址、最新版本号、module名字、开源许可证信息、文档（应该是集成了godoc返回的结果）、它的依赖、以及以它为依赖的项目(见下图)：</p>
<p><img src="https://tonybai.com/wp-content/uploads/go.dev/explore-3.png" alt="img{512x368}" /></p>
<h2>四. 小结</h2>
<p>go.dev目前处于最小产品状态(mvp)，从目前已经提供的栏目来看，go.dev能为gopher提供的帮助已经很全面了。后续go.dev站点的运营好坏（比如：信息更新是否及时等）将决定go.dev是否能达到其预期的期望。</p>
<p>go.dev目前似乎还缺少论坛功能。不过已有的<a href="https://groups.google.com/forum/#!topic/golang-nuts/">golang-nuts</a>、<a href="https://forum.golangbridge.org/">gobridge</a>已经承担了这个角色，但如果能有一个官方论坛（一站式）就再好不过了。</p>
<p>go.dev在国内可以访问，就是速度有些慢（可能因地区而异）。</p>
<hr />
<p>我的网课“<a href="https://coding.imooc.com/class/284.html">Kubernetes实战：高可用集群搭建、配置、运维与应用</a>”在慕课网上线了，感谢小伙伴们学习支持！</p>
<p><a href="https://tonybai.com/">我爱发短信</a>：企业级短信平台定制开发专家 https://tonybai.com/<br />
smspush : 可部署在企业内部的定制化短信平台，三网覆盖，不惧大并发接入，可定制扩展； 短信内容你来定，不再受约束, 接口丰富，支持长短信，签名可选。</p>
<p>著名云主机服务厂商DigitalOcean发布最新的主机计划，入门级Droplet配置升级为：1 core CPU、1G内存、25G高速SSD，价格5$/月。有使用DigitalOcean需求的朋友，可以打开这个<a href="https://m.do.co/c/bff6eed92687">链接地址</a>：https://m.do.co/c/bff6eed92687 开启你的DO主机之路。</p>
<p>Gopher Daily(Gopher每日新闻)归档仓库 &#8211; https://github.com/bigwhite/gopherdaily</p>
<p>我的联系方式：</p>
<p>微博：https://weibo.com/bigwhite20xx<br />
微信公众号：iamtonybai<br />
博客：tonybai.com<br />
github: https://github.com/bigwhite</p>
<p>微信赞赏：<br />
<img src="https://tonybai.com/wp-content/uploads/wechat-zanshang-code-512x512.jpg" alt="img{512x368}" /></p>
<p>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。</p>
<p style='text-align:left'>&copy; 2019, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2019/11/14/what-the-godev-website-bring-to-gophers/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>使用nomad实现集群管理和微服务部署调度</title>
		<link>https://tonybai.com/2019/03/30/cluster-management-and-microservice-deployment-and-scheduled-by-nomad/</link>
		<comments>https://tonybai.com/2019/03/30/cluster-management-and-microservice-deployment-and-scheduled-by-nomad/#comments</comments>
		<pubDate>Sat, 30 Mar 2019 11:21:09 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[cloud-native]]></category>
		<category><![CDATA[consul]]></category>
		<category><![CDATA[curl]]></category>
		<category><![CDATA[DaemonSet]]></category>
		<category><![CDATA[deployment]]></category>
		<category><![CDATA[dig]]></category>
		<category><![CDATA[DNS]]></category>
		<category><![CDATA[eBay]]></category>
		<category><![CDATA[fabio]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[group]]></category>
		<category><![CDATA[hashicorp]]></category>
		<category><![CDATA[hcl]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[https]]></category>
		<category><![CDATA[imooc]]></category>
		<category><![CDATA[istio]]></category>
		<category><![CDATA[job]]></category>
		<category><![CDATA[k8s]]></category>
		<category><![CDATA[kubeadm]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[loadbalance]]></category>
		<category><![CDATA[nomad]]></category>
		<category><![CDATA[pod]]></category>
		<category><![CDATA[Scheduler]]></category>
		<category><![CDATA[Service]]></category>
		<category><![CDATA[ServiceMesh]]></category>
		<category><![CDATA[sni]]></category>
		<category><![CDATA[SSL]]></category>
		<category><![CDATA[task]]></category>
		<category><![CDATA[TLS]]></category>
		<category><![CDATA[Trace]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[vault]]></category>
		<category><![CDATA[weave]]></category>
		<category><![CDATA[云原生]]></category>
		<category><![CDATA[容器]]></category>
		<category><![CDATA[微服务]]></category>
		<category><![CDATA[慕课网]]></category>
		<category><![CDATA[服务网格]]></category>
		<category><![CDATA[滚动升级]]></category>
		<category><![CDATA[蓝绿]]></category>
		<category><![CDATA[调度器]]></category>
		<category><![CDATA[负载均衡]]></category>
		<category><![CDATA[金丝雀]]></category>
		<category><![CDATA[集群]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=2689</guid>
		<description><![CDATA[在“云原生”、“容器化”、“微服务”、“服务网格”等概念大行其道的今天，一提到集群管理、容器工作负载调度，人们首先想到的是Kubernetes。 Kubernetes经过多年的发展，目前已经成为了云原生计算平台的事实标准，得到了诸如谷歌、微软、红帽、亚马逊、IBM、阿里等大厂的大力支持，各大云计算提供商也都提供了专属Kubernetes集群服务。开发人员可以一键在这些大厂的云上创建k8s集群。对于那些不愿被cloud provider绑定的组织或开发人员，Kubernetes也提供了诸如Kubeadm这样的k8s集群引导工具，帮助大家在裸金属机器上搭建自己的k8s集群，当然这样做的门槛较高（如果您想学习自己搭建和管理k8s集群，可以参考我在慕课网上发布的实战课《高可用集群搭建、配置、运维与应用》）。 Kubernetes的学习曲线是公认的较高，尤其是对于应用开发人员。再加上Kubernetes发展很快，越来越多的概念和功能加入到k8s技术栈，这让人们不得不考虑建立和维护这样一套集群所要付出的成本。人们也在考虑是否所有场景都需要部署一个k8s集群，是否有轻量级的且能满足自身需求的集群管理和微服务部署调度方案呢？外国朋友Matthias Endler就在其文章《也许你不需要Kubernetes》中给出一个轻量级的集群管理方案 &#8211; 使用hashicorp开源的nomad工具。 这让我想起了去年写的《基于consul实现微服务的服务发现和负载均衡》一文。文中虽然实现了基于consul的服务注册、发现以及负载均衡，但是缺少一个环节：那就是整个集群管理以及工作负载部署调度自动化的缺乏。nomad应该恰好可以补足这一短板，并且它足够轻量。本文我们就来探索和实践一下使用nomad实现集群管理和微服务部署调度。 一. 安装nomad集群 nomad是Hashicorp公司出品的集群管理和工作负荷调度器，支持多种驱动形式的工作负载调度，包括Docker容器、虚拟机、原生可执行程序等，并支持跨数据中心调度。Nomad不负责服务发现或密钥管理等 ，它将这些功能分别留给了HashiCorp的Consul和Vault。HashiCorp的创始人认为，这会使得Nomad更为轻量级，调度性能更高。 nomad使用Go语言实现，因此其本身仅仅是一个可执行的二进制文件。和Hashicorp其他工具产品(诸如：consul等)类似，nomad一个可执行文件既可以以server模式运行，亦可以client模式运行，甚至可以启动一个实例，既是server，也是client。 下面是nomad集群的架构图(来自hashicorp官方）: 一个nomad集群至少要包含一个server，作为集群的控制平面；一个或多个client则用于承载工作负荷。通常生产环境nomad集群的控制平面至少要有5个及以上的server才能在高可用上有一定保证。 建立一个nomad集群有多种方法，包括手工建立、基于consul自动建立和基于云自动建立。考虑到后续涉及微服务的注册发现，这里我们采用基于consul自动建立nomad集群的方法，下面是部署示意图： 我这里的试验环境仅有三台hosts，因此这三台host既承载consul集群，也承载nomad集群（包括server和client），即nomad的控制平面和工作负荷由这三台host一并承担了。 1. consul集群启动 在之前的《基于consul实现微服务的服务发现和负载均衡》一文中，我对consul集群的建立做过详细地说明，因此这里只列出步骤，不详细解释了。注意：这次consul的版本升级到了consul v1.4.4了。 在每个node上分别下载consul 1.4.4： # wget -c https://releases.hashicorp.com/consul/1.4.4/consul_1.4.4_linux_amd64.zip # unzip consul_1.4.4_linux_amd64.zip # cp consul /usr/local/bin # consul -v Consul v1.4.4 Protocol 2 spoken by default, understands 2 to 3 (agent will automatically use protocol &#62;2 when [...]]]></description>
			<content:encoded><![CDATA[<p>在<a href="https://www.cncf.io/">“云原生”</a>、<a href="https://tonybai.com/tag/docker">“容器化”</a>、<a href="https://en.wikipedia.org/wiki/Microservices">“微服务”</a>、<a href="https://tonybai.com/2018/01/03/an-intro-of-microservices-governance-by-istio/">“服务网格”</a>等概念大行其道的今天，一提到集群管理、容器工作负载调度，人们首先想到的是<a href="https://tonybai.com/tag/kubernetes">Kubernetes</a>。</p>
<p><a href="https://kubernetes.io/">Kubernetes</a>经过多年的发展，目前已经成为了云原生计算平台的事实标准，得到了诸如谷歌、微软、红帽、亚马逊、IBM、阿里等大厂的大力支持，各大云计算提供商也都提供了专属Kubernetes集群服务。开发人员可以<strong>一键</strong>在这些大厂的云上<a href="https://tonybai.com/2017/05/15/setup-a-ha-kubernetes-cluster-based-on-kubeadm-part1/">创建k8s集群</a>。对于那些不愿被cloud provider绑定的组织或开发人员，Kubernetes也提供了诸如<a href="https://tonybai.com/2017/05/15/setup-a-ha-kubernetes-cluster-based-on-kubeadm-part1/">Kubeadm</a>这样的k8s集群引导工具，帮助大家在裸金属机器上<a href="https://tonybai.com/2018/10/17/imooc-course-kubernetes-practice-go-online/">搭建自己的k8s集群</a>，当然这样做的门槛较高（如果您想学习自己搭建和管理k8s集群，可以参考我在<a href="https://www.imooc.com/">慕课网</a>上发布的实战课<a href="https://coding.imooc.com/class/284.html">《高可用集群搭建、配置、运维与应用》</a>）。</p>
<p>Kubernetes的学习曲线是公认的较高，尤其是对于应用开发人员。再加上Kubernetes发展很快，越来越多的概念和功能加入到k8s技术栈，这让人们不得不考虑建立和维护这样一套集群所要付出的成本。人们也在考虑是否所有场景都需要部署一个k8s集群，是否有轻量级的且能满足自身需求的集群管理和微服务部署调度方案呢？外国朋友Matthias Endler就在其文章<a href="https://matthias-endler.de/2019/maybe-you-dont-need-kubernetes/">《也许你不需要Kubernetes》</a>中给出一个轻量级的集群管理方案 &#8211; 使用<a href="https://www.hashicorp.com/">hashicorp</a>开源的<a href="https://github.com/hashicorp/nomad">nomad工具</a>。</p>
<p>这让我想起了去年写的<a href="https://tonybai.com/2018/09/10/setup-service-discovery-and-load-balance-based-on-consul/">《基于consul实现微服务的服务发现和负载均衡》</a>一文。文中虽然实现了基于<a href="https://tonybai.com/2015/07/06/implement-distributed-services-registery-and-discovery-by-consul/">consul</a>的服务注册、发现以及负载均衡，但是缺少一个环节：那就是整个集群管理以及工作负载部署调度自动化的缺乏。nomad应该恰好可以补足这一短板，并且它足够轻量。本文我们就来探索和实践一下使用<a href="https://github.com/hashicorp/nomad">nomad</a>实现集群管理和微服务部署调度。</p>
<h2>一. 安装nomad集群</h2>
<p>nomad是Hashicorp公司出品的集群管理和工作负荷调度器，支持多种驱动形式的工作负载调度，包括<a href="https://tonybai.com/tag/docker">Docker容器</a>、虚拟机、原生可执行程序等，并支持跨数据中心调度。Nomad不负责服务发现或密钥管理等 ，它将这些功能分别留给了HashiCorp的<a href="https://tonybai.com/tag/consul">Consul</a>和<a href="https://github.com/hashicorp/vault">Vault</a>。HashiCorp的创始人认为，这会使得Nomad更为轻量级，调度性能更高。</p>
<p>nomad使用<a href="https://tonybai.com/tag/golang">Go语言</a>实现，因此其本身仅仅是一个可执行的二进制文件。和Hashicorp其他工具产品(诸如：consul等)类似，nomad一个可执行文件既可以以server模式运行，亦可以client模式运行，甚至可以启动一个实例，既是server，也是client。</p>
<p>下面是nomad集群的架构图(来自hashicorp官方）:</p>
<p><img src="https://tonybai.com/wp-content/uploads/nomad-arch.png" alt="img{512x368}" /></p>
<p>一个nomad集群至少要包含一个server，作为集群的控制平面；一个或多个client则用于承载工作负荷。通常生产环境nomad集群的控制平面至少要有5个及以上的server才能在高可用上有一定保证。</p>
<p>建立一个nomad集群有多种方法，包括手工建立、基于consul自动建立和基于云自动建立。考虑到后续涉及微服务的注册发现，这里我们采用基于consul自动建立nomad集群的方法，下面是部署示意图：</p>
<p><img src="https://tonybai.com/wp-content/uploads/nomad-cluster-bootstrap-from-consul-cluster-on-ubuntu-hosts.png" alt="img{512x368}" /></p>
<p>我这里的试验环境仅有三台hosts，因此这三台host既承载consul集群，也承载nomad集群（包括server和client），即nomad的控制平面和工作负荷由这三台host一并承担了。</p>
<h3>1. consul集群启动</h3>
<p>在之前的<a href="https://tonybai.com/2018/09/10/setup-service-discovery-and-load-balance-based-on-consul/">《基于consul实现微服务的服务发现和负载均衡》</a>一文中，我对consul集群的建立做过详细地说明，因此这里只列出步骤，不详细解释了。注意：这次consul的版本升级到了consul v1.4.4了。</p>
<p>在每个node上分别下载consul 1.4.4：</p>
<pre><code># wget -c https://releases.hashicorp.com/consul/1.4.4/consul_1.4.4_linux_amd64.zip
# unzip consul_1.4.4_linux_amd64.zip

# cp consul /usr/local/bin

# consul -v

Consul v1.4.4
Protocol 2 spoken by default, understands 2 to 3 (agent will automatically use protocol &gt;2 when speaking to compatible agents)

</code></pre>
<p>启动consul集群：(每个node上创建~/.bin/consul-install目录，并进入该目录下执行)</p>
<pre><code>dxnode1:

# nohup consul agent -server -ui -dns-port=53 -bootstrap-expect=3 -data-dir=~/.bin/consul-install/consul-data -node=consul-1 -client=0.0.0.0 -bind=172.16.66.102 -datacenter=dc1 &gt; consul-1.log &amp; 2&gt;&amp;1

dxnode2:

# nohup consul agent -server -ui -dns-port=53  -bootstrap-expect=3 -data-dir=/root/consul-install/consul-data -node=consul-2 -client=0.0.0.0 -bind=172.16.66.103 -datacenter=dc1 -join 172.16.66.102 &gt; consul-2.log &amp; 2&gt;&amp;1

dxnode3:

nohup consul agent -server -ui -dns-port=53  -bootstrap-expect=3 -data-dir=/root/consul-install/consul-data -node=consul-3 -client=0.0.0.0 -bind=172.16.66.104 -datacenter=dc1 -join 172.16.66.102 &gt; consul-3.log &amp; 2&gt;&amp;1

</code></pre>
<p>consul集群启动结果查看如下：</p>
<pre><code># consul members
Node      Address             Status  Type    Build  Protocol  DC   Segment
consul-1  172.16.66.102:8301  alive   server  1.4.4  2         dc1  &lt;all&gt;
consul-2  172.16.66.103:8301  alive   server  1.4.4  2         dc1  &lt;all&gt;
consul-3  172.16.66.104:8301  alive   server  1.4.4  2         dc1  &lt;all&gt;

# consul operator raft list-peers
Node      ID                                    Address             State     Voter  RaftProtocol
consul-3  d048e55b-5f6a-34a4-784c-e6607db0e89e  172.16.66.104:8300  leader    true   3
consul-1  160a7a20-f177-d2f5-0765-e6d1a9a1a9a4  172.16.66.102:8300  follower  true   3
consul-2  6795cd2c-fad5-9d4f-2531-13b0a65e0893  172.16.66.103:8300  follower  true   3

</code></pre>
<h3>2. DNS设置（可选）</h3>
<p>如果采用基于consul DNS的方式进行服务发现，那么在每个<strong>nomad client node</strong>上设置DNS则很必要。否则如果要是基于consul service catalog的API去查找service，则可忽略这个步骤。设置步骤如下：</p>
<p>在每个node上，创建和编辑/etc/resolvconf/resolv.conf.d/base，填入如下内容：</p>
<pre><code>nameserver {consul-1-ip}
nameserver {consul-2-ip}

</code></pre>
<p>然后重启resolvconf服务:</p>
<pre><code>#  /etc/init.d/resolvconf restart
[ ok ] Restarting resolvconf (via systemctl): resolvconf.service.

</code></pre>
<p>新的resolv.conf将变成：</p>
<pre><code># cat /etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver {consul-1-ip}
nameserver {consul-2-ip}
nameserver 100.100.2.136
nameserver 100.100.2.138
options timeout:2 attempts:3 rotate single-request-reopen

</code></pre>
<p>这样无论是在host上，还是在新启动的container里就都可以访问到xx.xx.consul域名的服务了：</p>
<pre><code># ping -c 3 consul.service.dc1.consul
PING consul.service.dc1.consul (172.16.66.103) 56(84) bytes of data.
64 bytes from 172.16.66.103: icmp_seq=1 ttl=64 time=0.227 ms
64 bytes from 172.16.66.103: icmp_seq=2 ttl=64 time=0.158 ms
^C
--- consul.service.dc1.consul ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.158/0.192/0.227/0.037 ms

# docker run busybox ping -c 3 consul.service.dc1.consul

PING consul.service.dc1.consul (172.16.66.104): 56 data bytes
64 bytes from 172.16.66.104: seq=0 ttl=64 time=0.067 ms
64 bytes from 172.16.66.104: seq=1 ttl=64 time=0.061 ms
64 bytes from 172.16.66.104: seq=2 ttl=64 time=0.076 ms

--- consul.service.dc1.consul ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.061/0.068/0.076 ms

</code></pre>
<h3>3. 基于consul集群引导启动nomad集群</h3>
<p>按照之前的拓扑图，我们需先在每个node上分别下载nomad：</p>
<pre><code># wget -c https://releases.hashicorp.com/nomad/0.8.7/nomad_0.8.7_linux_amd64.zip

# unzip nomad_0.8.7_linux_amd64.zip.zip

# cp ./nomad /usr/local/bin

# nomad -v

Nomad v0.8.7 (21a2d93eecf018ad2209a5eab6aae6c359267933+CHANGES)

</code></pre>
<p>我们已经建立了consul集群，因为我们将采用<a href="https://www.nomadproject.io/guides/operations/cluster/automatic.html">基于consul集群引导启动nomad集群</a>这一创建nomad集群的最Easy方式。同时，我们每个node上既要运行nomad server，也要nomad client，于是我们在nomad的配置文件中，对server和client都设置为”enabled = true”。下面是nomad启动的配置文件，每个node上的nomad均将该配置文件作为为输入：</p>
<pre><code>// agent.hcl

data_dir = "/root/.bin/nomad-install/nomad.d"

server {
  enabled = true
  bootstrap_expect = 3
}

client {
  enabled = true
}

</code></pre>
<p>下面是在各个节点上启动nomad的操作步骤：</p>
<pre><code>dxnode1:

# nohup nomad agent -config=/root/.bin/nomad-install/agent.hcl  &gt; nomad-1.log &amp; 2&gt;&amp;1

dxnode2:

# nohup nomad agent -config=/root/.bin/nomad-install/agent.hcl  &gt; nomad-2.log &amp; 2&gt;&amp;1

dxnode3:

# nohup nomad agent -config=/root/.bin/nomad-install/agent.hcl  &gt; nomad-3.log &amp; 2&gt;&amp;1

</code></pre>
<p>查看nomad集群的启动结果：</p>
<pre><code>#  nomad server members
Name            Address        Port  Status  Leader  Protocol  Build  Datacenter  Region
dxnode1.global  172.16.66.102  4648  alive   true    2         0.8.7  dc1         global
dxnode2.global  172.16.66.103  4648  alive   false   2         0.8.7  dc1         global
dxnode3.global  172.16.66.104  4648  alive   false   2         0.8.7  dc1         global

# nomad operator raft list-peers

Node            ID                  Address             State     Voter  RaftProtocol
dxnode1.global  172.16.66.102:4647  172.16.66.102:4647  leader    true   2
dxnode2.global  172.16.66.103:4647  172.16.66.103:4647  follower  true   2
dxnode3.global  172.16.66.104:4647  172.16.66.104:4647  follower  true   2

# nomad node-status
ID        DC   Name     Class   Drain  Eligibility  Status
7acdd7bc  dc1  dxnode1  &lt;none&gt;  false  eligible     ready
c281658a  dc1  dxnode3  &lt;none&gt;  false  eligible     ready
9e3ef19f  dc1  dxnode2  &lt;none&gt;  false  eligible     ready

</code></pre>
<p>以上这些命令的结果都显示nomad集群工作正常！</p>
<p>nomad还提供一个ui界面（http://nomad-node-ip:4646/ui），可以让运维人员以可视化的方式直观看到当前nomad集群的状态，包括server、clients、工作负载(job)的情况：</p>
<p><img src="https://tonybai.com/wp-content/uploads/nomad-ui.png" alt="img{512x368}" /></p>
<p>nomad ui首页</p>
<p><img src="https://tonybai.com/wp-content/uploads/nomad-ui-servers.png" alt="img{512x368}" /></p>
<p>nomad server列表和状态</p>
<p><img src="https://tonybai.com/wp-content/uploads/nomad-ui-clients.png" alt="img{512x368}" /></p>
<p>nomad client列表和状态</p>
<h2>二. 部署工作负载</h2>
<p>引导启动成功nomad集群后，我们接下来就要向集群中添加“工作负载”了。</p>
<p>在<a href="https://coding.imooc.com/class/284.html">Kubernetes</a>中，我们可以通过创建deployment、pod等向集群添加工作负载；在nomad中我们也可以通过类似的声明式的方法向nomad集群添加工作负载。不过nomad相对简单许多，它<strong>仅提供了一种</strong>名为job的抽象，并给出了<a href="https://www.nomadproject.io/docs/job-specification/index.html">job的specification</a>。nomad集群所有关于工作负载的操作均通过job描述文件和nomad job相关子命令完成。下面是通过job部署工作负载的流程示意图：</p>
<p><img src="https://tonybai.com/wp-content/uploads/nomad-job-workflow.png" alt="img{512x368}" /></p>
<p>从图中可以看到，我们需要做的仅仅是将编写好的job文件提交给nomad即可。</p>
<p>Job spec定义了：job -> group -> task的层次关系。每个job文件只有一个job，但是一个job可能有多个group，每个group可能有多个task。group包含一组要放在同一个集群中调度的task。一个Nomad task是由其驱动程序（driver）在Nomad client节点上执行的命令、服务、应用程序或其他工作负载。task可以是短时间的批处理作业（batch）或长时间运行的服务(service)，例如web应用程序、数据库服务器或API。</p>
<p>Tasks是在用<a href="https://github.com/hashicorp/hcl">HCL语法</a>的声明性job规范中定义的。Job文件提交给Nomad服务端，服务端决定在何处以及如何将job文件中定义的task分配给客户端节点。另一种概念化的理解是:job规范表示工作负载的期望状态，Nomad服务端创建并维护其实际状态。</p>
<p>通过job，开发人员还可以为工作负载定义约束和资源。约束（constraint）通过内核类型和版本等属性限制了工作负载在节点上的位置。资源（resources）需求包括运行task所需的内存、网络、CPU等。</p>
<p>有三种类型的job：system、service和batch，它们决定Nomad将用于此job中task的调度器。service 调度器被设计用来调度永远不会宕机的长寿命服务。batch作业对短期性能波动的敏感性要小得多，寿命也很短，几分钟到几天就可以完成。system调度器用于注册应该在满足作业约束的所有nomad client上运行的作业。当某个client加入到nomad集群或转换到就绪状态时也会调用它。</p>
<p>Nomad允许job作者为自动重新启动失败和无响应的任务指定策略，并自动将失败的任务重新调度到其他节点，从而使任务工作负载具有弹性。</p>
<p>如果对应到k8s中的概念，group更像是某种controller，而task更类似于pod，是被真实调度的实体。Job spec对应某个k8s api object的spec，具体体现在某个yaml文件中。</p>
<p>下面我们就来真实地在nomad集群中创建一个工作负载。我们使用之前在<a href="https://tonybai.com/2018/09/10/setup-service-discovery-and-load-balance-based-on-consul/">《基于consul实现微服务的服务发现和负载均衡》</a>一文中使用过的那几个demo image，这里我们先使用<a href="https://hub.docker.com/r/bigwhite/httpbackendservice">httpbackendservice镜像</a>来创建一个job。</p>
<p>下面是httpbackend的job文件：</p>
<pre><code>// httpbackend-1.nomad

job "httpbackend" {
  datacenters = ["dc1"]
  type = "service"

  group "httpbackend" {
    count = 2

    task "httpbackend" {
      driver = "docker"
      config {
        image = "bigwhite/httpbackendservice:v1.0.0"
        port_map {
          http = 8081
        }
        logging {
          type = "json-file"
        }
      }

      resources {
        network {
          mbits = 10
          port "http" {}
        }
      }

      service {
        name = "httpbackend"
        port = "http"
      }
    }
  }
}

</code></pre>
<p>这个文件基本都是自解释的，重点提几个地方：</p>
<ul>
<li>
<p>job type: service ： 说明该job创建和调度的是一个service类型的工作负载；</p>
</li>
<li>
<p>count = 2 ： 类似于k8s的replicas字段，期望在nomad集群中运行2个httpbackend服务实例，nomad来保证始终处于期望状态。</p>
</li>
<li>
<p>关于port：port_map指定了task中容器的监听端口。network中的port “http” {}没有指定静态IP，因此将采用动态主机端口。service中的port则指明使用”http”这个tag的动态主机端口。这和k8s中service中port使用名称匹配的方式映射到具体pod中的port的方法类似。</p>
</li>
</ul>
<p>我们使用nomad job子命令来创建该工作负载。正式创建之前，我们可以先通过nomad job plan来dry-run一下，一是看job文件格式是否ok；二来检查一下nomad集群是否有空余资源创建和调度新的工作负载：</p>
<pre><code># nomad job plan httpbackend-1.nomad
+/- Job: "httpbackend"
+/- Stop: "true" =&gt; "false"
    Task Group: "httpbackend" (2 create)
      Task: "httpbackend"

Scheduler dry-run:
- All tasks successfully allocated.

Job Modify Index: 4248
To submit the job with version verification run:

nomad job run -check-index 4248 httpbackend-1.nomad

When running the job with the check-index flag, the job will only be run if the
server side version matches the job modify index returned. If the index has
changed, another user has modified the job and the plan's results are
potentially invalid.

</code></pre>
<p>如果plan的输出结果没有问题，则可以用nomad job run正式创建和调度job：</p>
<pre><code># nomad job run httpbackend-1.nomad
==&gt; Monitoring evaluation "40c63529"
    Evaluation triggered by job "httpbackend"
    Allocation "6b0b83de" created: node "9e3ef19f", group "httpbackend"
    Allocation "d0710b85" created: node "7acdd7bc", group "httpbackend"
    Evaluation status changed: "pending" -&gt; "complete"
==&gt; Evaluation "40c63529" finished with status "complete"

</code></pre>
<p>接下来，我们可以使用nomad job status命令查看job的创建情况以及某个job的详细状态信息：</p>
<pre><code># nomad job status
ID                  Type     Priority  Status   Submit Date
httpbackend         service  50        running  2019-03-30T04:58:09+08:00

# nomad job status httpbackend
ID            = httpbackend
Name          = httpbackend
Submit Date   = 2019-03-30T04:58:09+08:00
Type          = service
Priority      = 50
Datacenters   = dc1
Status        = running
Periodic      = false
Parameterized = false

Summary
Task Group   Queued  Starting  Running  Failed  Complete  Lost
httpbackend  0       0         2        0       0         0

Allocations
ID        Node ID   Task Group   Version  Desired  Status    Created    Modified
6b0b83de  9e3ef19f  httpbackend  11       run      running   8m ago     7m50s ago
d0710b85  7acdd7bc  httpbackend  11       run      running   8m ago     7m39s ago

</code></pre>
<p>前面说过，nomad只是集群管理和负载调度，服务发现它是不管的，并且服务发现的问题早已经被consul解决掉了。所以httpbackend创建后，要想使用该服务，我们还得走consul提供的路线：</p>
<p>DNS方式(前面已经做过铺垫了)：</p>
<pre><code># dig SRV httpbackend.service.dc1.consul

; &lt;&lt;&gt;&gt; DiG 9.10.3-P4-Ubuntu &lt;&lt;&gt;&gt; SRV httpbackend.service.dc1.consul
;; global options: +cmd
;; Got answer:
;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, status: NOERROR, id: 7742
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 5
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;httpbackend.service.dc1.consul.    IN    SRV

;; ANSWER SECTION:
httpbackend.service.dc1.consul.    0 IN    SRV    1 1 23578 consul-1.node.dc1.consul.
httpbackend.service.dc1.consul.    0 IN    SRV    1 1 22819 consul-2.node.dc1.consul.

;; ADDITIONAL SECTION:
consul-1.node.dc1.consul. 0    IN    A    172.16.66.102
consul-1.node.dc1.consul. 0    IN    TXT    "consul-network-segment="
consul-2.node.dc1.consul. 0    IN    A    172.16.66.103
consul-2.node.dc1.consul. 0    IN    TXT    "consul-network-segment="

;; Query time: 471 msec
;; SERVER: 172.16.66.102#53(172.16.66.102)
;; WHEN: Sat Mar 30 05:07:54 CST 2019
;; MSG SIZE  rcvd: 251

# curl http://172.16.66.102:23578
this is httpbackendservice, version: v1.0.0

# curl http://172.16.66.103:22819
this is httpbackendservice, version: v1.0.0

</code></pre>
<p>或http api方式(可通过<a href="https://godoc.org/github.com/hashicorp/consul/api">官方API</a>查询服务)：</p>
<pre><code># curl http://127.0.0.1:8500/v1/health/service/httpbackend

[
    {
        "Node": {"ID":"160a7a20-f177-d2f5-0765-e6d1a9a1a9a4","Node":"consul-1","Address":"172.16.66.102","Datacenter":"dc1","TaggedAddresses":{"lan":"172.16.66.102","wan":"172.16.66.102"},"Meta":{"consul-network-segment":""},"CreateIndex":7,"ModifyIndex":10},
        "Service": {"ID":"_nomad-task-5uxc3b7hjzivbklslt4yj5bpsfagibrb","Service":"httpbackend","Tags":[],"Address":"172.16.66.102","Meta":null,"Port":23578,"Weights":{"Passing":1,"Warning":1},"EnableTagOverride":false,"ProxyDestination":"","Proxy":{},"Connect":{},"CreateIndex":30727,"ModifyIndex":30727},
        "Checks": [{"Node":"consul-1","CheckID":"serfHealth","Name":"Serf Health Status","Status":"passing","Notes":"","Output":"Agent alive and reachable","ServiceID":"","ServiceName":"","ServiceTags":[],"Definition":{},"CreateIndex":7,"ModifyIndex":7}]
    },
    {
        "Node": {"ID":"6795cd2c-fad5-9d4f-2531-13b0a65e0893","Node":"consul-2","Address":"172.16.66.103","Datacenter":"dc1","TaggedAddresses":{"lan":"172.16.66.103","wan":"172.16.66.103"},"Meta":{"consul-network-segment":""},"CreateIndex":5,"ModifyIndex":5},
        "Service": {"ID":"_nomad-task-hvqnbklzqr6q5mpspqcqbnhxdil4su4d","Service":"httpbackend","Tags":[],"Address":"172.16.66.103","Meta":null,"Port":22819,"Weights":{"Passing":1,"Warning":1},"EnableTagOverride":false,"ProxyDestination":"","Proxy":{},"Connect":{},"CreateIndex":30725,"ModifyIndex":30725},
        "Checks": [{"Node":"consul-2","CheckID":"serfHealth","Name":"Serf Health Status","Status":"passing","Notes":"","Output":"Agent alive and reachable","ServiceID":"","ServiceName":"","ServiceTags":[],"Definition":{},"CreateIndex":8,"ModifyIndex":8}]
    }
]

</code></pre>
<h2>三. 将服务暴露到外部以及负载均衡</h2>
<p>集群内部的东西向流量可以通过consul的服务发现来实现，南北向流量则需要我们将部分服务暴露到外部才能实现流量导入。在<a href="https://tonybai.com/2018/09/10/setup-service-discovery-and-load-balance-based-on-consul/">《基于consul实现微服务的服务发现和负载均衡》</a>一文中，我们是通过<a href="https://tonybai.com/tag/nginx">nginx</a>实现服务暴露和负载均衡的，但是需要<a href="https://github.com/hashicorp/consul-template">consul-template</a>的协助，并且自己需要实现一个nginx的配置模板，门槛较高也比较复杂。</p>
<p>nomad的官方文档推荐了<a href="https://github.com/fabiolb/fabio">fabio</a>这个反向代理和负载均衡工具。fabio最初由位于荷兰的“<a href="https://www.ebayclassifiedsgroup.com/">eBay Classifieds Group</a>”开发，它为荷兰（marktplaats.nl），澳大利亚（gumtree.com.au）和意大利（www.kijiji.it）的一些最大网站提供支持。自2015年9月以来，它为这些站点提供23000个请求/秒的处理能力(性能应对一般中等流量是没有太大问题的)，没有发现重大问题。</p>
<p>与consul-template+nginx的组合不同，fabio无需开发人员做任何二次开发，也不需要自定义模板，它直接从consul读取service list并生成相关路由。至于哪些服务要暴露在外部，路由形式是怎样的，是需要在服务启动时为服务设置特定的tag，fabio定义了一套灵活的路由匹配描述方法。</p>
<p>下面我们就来部署fabio，并将上面的httpbackend暴露到外部。</p>
<h3>1. 部署fabio</h3>
<p>fabio也是nomad集群的一个工作负载，因此我们可以像普通job那样部署fabio。我们先来使用nomad官方文档中给出fabio.nomad：</p>
<pre><code>//fabio.nomad

job "fabio" {
  datacenters = ["dc1"]
  type = "system"

  group "fabio" {
    task "fabio" {
      driver = "docker"
      config {
        image = "fabiolb/fabio"
        network_mode = "host"
        logging {
          type = "json-file"
        }
      }

      resources {
        cpu    = 200
        memory = 128
        network {
          mbits = 20
          port "lb" {
            static = 9999
          }
          port "ui" {
            static = 9998
          }
        }
      }
    }
  }
}

</code></pre>
<p>这里有几点值得注意：</p>
<ol>
<li>
<p>fabio job的类型是”system”，也就是说该job会被部署到job可以匹配到（通过设定的约束条件）的所有nomad client上，且每个client上仅部署一个实例，有些类似于k8s的daemonset控制下的pod；</p>
</li>
<li>
<p>network_mode = “host” 告诉fabio的驱动docker：fabio容器使用host网络，即与主机同网络namespace；</p>
</li>
<li>
<p>static = 9999和static = 9998，说明fabio在每个nomad client上监听固定的静态端口而不是使用动态端口。这也要求了每个nomad client上不允许存在与fabio端口冲突的应用启动。</p>
</li>
</ol>
<p>我们来plan和run一下这个fabio job：</p>
<pre><code># nomad job plan fabio.nomad

+ Job: "fabio"
+ Task Group: "fabio" (3 create)
  + Task: "fabio" (forces create)

Scheduler dry-run:
- All tasks successfully allocated.

Job Modify Index: 0
To submit the job with version verification run:

nomad job run -check-index 0 fabio.nomad

When running the job with the check-index flag, the job will only be run if the
server side version matches the job modify index returned. If the index has
changed, another user has modified the job and the plan's results are
potentially invalid.

# nomad job run fabio.nomad
==&gt; Monitoring evaluation "97bfc16d"
    Evaluation triggered by job "fabio"
    Allocation "1b77dcfa" created: node "c281658a", group "fabio"
    Allocation "da35a778" created: node "7acdd7bc", group "fabio"
    Allocation "fc915ab7" created: node "9e3ef19f", group "fabio"
    Evaluation status changed: "pending" -&gt; "complete"
==&gt; Evaluation "97bfc16d" finished with status "complete"

</code></pre>
<p>查看一下fabio job的运行状态：</p>
<pre><code># nomad job status fabio

ID            = fabio
Name          = fabio
Submit Date   = 2019-03-27T14:30:29+08:00
Type          = system
Priority      = 50
Datacenters   = dc1
Status        = running
Periodic      = false
Parameterized = false

Summary
Task Group  Queued  Starting  Running  Failed  Complete  Lost
fabio       0       0         3        0       0         0

Allocations
ID        Node ID   Task Group  Version  Desired  Status   Created    Modified
1b77dcfa  c281658a  fabio       0        run      running  1m11s ago  58s ago
da35a778  7acdd7bc  fabio       0        run      running  1m11s ago  54s ago
fc915ab7  9e3ef19f  fabio       0        run      running  1m11s ago  58s ago

</code></pre>
<p>通过9998端口，可以查看fabio的ui页面，这个页面主要展示的是fabio生成的路由信息：</p>
<p><img src="https://tonybai.com/wp-content/uploads/fabio-ui-routes-table-1.png" alt="img{512x368}" /></p>
<p>由于尚未暴露任何服务，因此fabio的路由表为空。</p>
<p>fabio的流量入口为9999端口，不过由于没有配置路由和upstream service，因此如果此时向9999端口发送http请求，将会得到404的应答。</p>
<h3>2. 暴露HTTP服务到外部</h3>
<p>接下来，我们就将上面创建的httpbackend服务通过fabiolb暴露到外部，使得特定条件下通过fabiolb进入集群内部的流量可以被准确路由到集群中的httpbackend实例上面。</p>
<p>下面是fabio将nomad集群内部服务暴露在外部的原理图：</p>
<p><img src="https://tonybai.com/wp-content/uploads/fabiolb-mechanism.png" alt="img{512x368}" /></p>
<p>我们看到原理图中最为关键的一点就是service tag，该信息由nomad在创建job时写入到consul集群；fabio监听consul集群service信息变更，读取有新变动的job，解析job的service tag，生成路由规则。fabio关注所有带有”urlprefix-”前缀的service tag。</p>
<p>fabio启动时监听的9999端口，默认是http接入。我们修改一下之前的httpbackend.nomad，为该job中的service增加tag字段：</p>
<pre><code>// httpbackend.nomad

... ...

     service {
        name = "httpbackend"
        tags = ["urlprefix-mysite.com:9999/"]
        port = "http"
        check {
          name     = "alive"
          type     = "http"
          path     = "/"
          interval = "10s"
          timeout  = "2s"
        }
      }

</code></pre>
<p>对于上面httpbackend.nomad中service块的变更，主要有两点：</p>
<p>1) 增加tag：匹配的路由信息为：“mysite.com:9999/”</p>
<p>2) 增加check块：如果没有check设置，该路由信息将不会在fabio中生效</p>
<p>更新一下httpbackend:</p>
<pre><code># nomad job run httpbackend-2.nomad
==&gt; Monitoring evaluation "c83af3d3"
    Evaluation triggered by job "httpbackend"
    Allocation "6b0b83de" modified: node "9e3ef19f", group "httpbackend"
    Allocation "d0710b85" modified: node "7acdd7bc", group "httpbackend"
    Evaluation status changed: "pending" -&gt; "complete"
==&gt; Evaluation "c83af3d3" finished with status "complete"

</code></pre>
<p>查看fabio的route表，可以看到增加了两条新路由信息：</p>
<p><img src="https://tonybai.com/wp-content/uploads/httpbackend-routes.png" alt="img{512x368}" /></p>
<p>我们通过fabio来访问一下httpbackend服务：</p>
<pre><code># curl http://mysite.com:9999/      --- 注意：事先已经在/etc/hosts中添加了 mysite.com的地址为127.0.0.1
this is httpbackendservice, version: v1.0.0

</code></pre>
<p>我们看到httpbackend service已经被成功暴露到lb的外部了。</p>
<h2>四. 暴露HTTPS、TCP服务到外部</h2>
<h3>1. 定制fabio</h3>
<p>我们的目标是将https、tcp服务暴露到lb的外部，nomad官方文档中给出的fabio.nomad将不再适用，我们需要让fabio监听多个端口，每个端口有着不同的用途。同时，我们通过给fabio传入适当的命令行参数来帮助我们查看fabio的详细access日志信息，并让fabio支持<a href="https://github.com/fabiolb/fabio/wiki/Features#request-tracing">TRACE机制</a>。</p>
<p>fabio.nomad调整如下：</p>
<pre><code>job "fabio" {
  datacenters = ["dc1"]
  type = "system"

  group "fabio" {
    task "fabio" {
      driver = "docker"
      config {
        image = "fabiolb/fabio"
        network_mode = "host"
        logging {
          type = "json-file"
        }
        args = [
          "-proxy.addr=:9999;proto=http,:9997;proto=tcp,:9996;proto=tcp+sni",
          "-log.level=TRACE",
          "-log.access.target=stdout"
        ]
      }

      resources {
        cpu    = 200
        memory = 128
        network {
          mbits = 20
        }
      }
    }
  }
}

</code></pre>
<p>我们让fabio监听三个端口：</p>
<ul>
<li>
<p>9999: http端口</p>
</li>
<li>
<p>9997: tcp端口</p>
</li>
<li>
<p>9996: tcp+sni端口</p>
</li>
</ul>
<p>后续会针对这三个端口暴露的不同服务做细致说明。</p>
<p>我们将fabio的日志级别调低为TRACE级别，以便能查看到fabio日志中输出的trace信息，帮助我们进行路由匹配的诊断。</p>
<p>重新nomad job run fabio.nomad后，我们来看看TRACE的效果：</p>
<pre><code>//访问后端服务，在http header中添加"Trace: abc"：

# curl -H 'Trace: abc' 'http://mysite.com:9999/'
this is httpbackendservice, version: v1.0.0

//查看fabio的访问日志：

2019/03/30 08:13:15 [TRACE] abc Tracing mysite.com:9999/
2019/03/30 08:13:15 [TRACE] abc Matching hosts: [mysite.com:9999]
2019/03/30 08:13:15 [TRACE] abc Match mysite.com:9999/
2019/03/30 08:13:15 [TRACE] abc Routing to service httpbackend on http://172.16.66.102:23578/
127.0.0.1 - - [30/Mar/2019:08:13:15 +0000] "GET / HTTP/1.1" 200 44

</code></pre>
<p>我们可以清晰的看到fabio收到请求后，匹配到一条路由：”mysite.com:9999/”，然后将http请求转发到 172.16.66.102:23578这个httpbackend服务实例上去了。</p>
<h3>2. https服务</h3>
<p>接下来，我们考虑将一个https服务暴露在lb外部。</p>
<p>一种方案是fabiolb做ssl termination，然后再在与upstream https服务建立的ssl连接上传递数据。这种两段式https通信是比较消耗资源的，fabio要对数据进行两次加解密。</p>
<p>另外一种方案是fabiolb将收到的请求透传给后面的upsteam https服务，由client与upsteam https服务直接建立“安全数据通道”，这个方案我们在后续会提到。</p>
<p>第三种方案，那就是对外依旧暴露http，但是fabiolb与upsteam之间通过https通信。我们先来看一下这种“间接暴露https”的方案。</p>
<pre><code>// httpsbackend-upstreamhttps.nomad

job "httpsbackend" {
  datacenters = ["dc1"]
  type = "service"

  group "httpsbackend" {
    count = 2
    restart {
      attempts = 2
      interval = "30m"
      delay = "15s"
      mode = "fail"
    }

    task "httpsbackend" {
      driver = "docker"
      config {
        image = "bigwhite/httpsbackendservice:v1.0.0"
        port_map {
          https = 7777
        }
        logging {
          type = "json-file"
        }
      }

      resources {
        network {
          mbits = 10
          port "https" {}
        }
      }

      service {
        name = "httpsbackend"
        tags = ["urlprefix-mysite-https.com:9999/ proto=https tlsskipverify=true"]
        port = "https"
        check {
          name     = "alive"
          type     = "tcp"
          path     = "/"
          interval = "10s"
          timeout  = "2s"
        }
      }
    }
  }
}

</code></pre>
<p>我们将创建名为httpsbackend的job，job中Task对应的tag为：”urlprefix-mysite-https.com:9999/ proto=https tlsskipverify=true”。解释为：路由mysite-https.com:9999/，上游upstream服务为https服务，fabio不验证upstream服务的公钥数字证书。</p>
<p>我们创建该job：</p>
<pre><code># nomad job run httpsbackend-upstreamhttps.nomad
==&gt; Monitoring evaluation "ba7af6d4"
    Evaluation triggered by job "httpsbackend"
    Allocation "3127aac8" created: node "7acdd7bc", group "httpsbackend"
    Allocation "b5f1b7a7" created: node "9e3ef19f", group "httpsbackend"
    Evaluation status changed: "pending" -&gt; "complete"
==&gt; Evaluation "ba7af6d4" finished with status "complete"

</code></pre>
<p>我们来通过fabiolb访问一下httpsbackend这个服务：</p>
<pre><code># curl -H "Trace: abc"  http://mysite-https.com:9999/
this is httpsbackendservice, version: v1.0.0

// fabiolb 日志

2019/03/30 09:35:48 [TRACE] abc Tracing mysite-https.com:9999/
2019/03/30 09:35:48 [TRACE] abc Matching hosts: [mysite-https.com:9999]
2019/03/30 09:35:48 [TRACE] abc Match mysite-https.com:9999/
2019/03/30 09:35:48 [TRACE] abc Routing to service httpsbackend on https://172.16.66.103:29248
127.0.0.1 - - [30/Mar/2019:09:35:48 +0000] "GET / HTTP/1.1" 200 45

</code></pre>
<h3>3. 基于tcp代理暴露https服务</h3>
<p>上面的方案虽然将https暴露在外面，但是client到fabio这个环节的数据传输不是在安全通道中。上面提到的方案2：fabiolb将收到的请求透传给后面的upsteam https服务，由client与upsteam https服务直接建立“安全数据通道”似乎更佳。fabiolb支持tcp端口的反向代理，我们基于tcp代理来暴露https服务到外部。</p>
<p>我们建立httpsbackend-tcp.nomad文件，考虑篇幅有限，我们仅列出差异化的部分：</p>
<pre><code>job "httpsbackend-tcp" {

 ... ...

    service {
        name = "httpsbackend-tcp"
        tags = ["urlprefix-:9997 proto=tcp"]
        port = "https"
        check {
          name     = "alive"
          type     = "tcp"
          path     = "/"
          interval = "10s"
          timeout  = "2s"
        }
      }

... ...

}

</code></pre>
<p>从httpsbackend-tcp.nomad文件，我们看到我们在9997这个tcp端口上暴露服务，tag为：“urlprefix-:9997 proto=tcp”，即凡是到达9997端口的流量，无论应用协议类型是什么，都转发到httpsbackend-tcp上，且通过tcp协议转发。</p>
<p>我们创建并测试一下该方案：</p>
<pre><code># nomad job run httpsbackend-tcp.nomad

# curl -k https://localhost:9997   //由于使用的是自签名证书，所有告诉curl不校验server端公钥数字证书
this is httpsbackendservice, version: v1.0.0

</code></pre>
<h3>4. 多个https服务共享一个fabio端口</h3>
<p>上面的基于tcp代理暴露https服务的方案还有一个问题，那就是每个https服务都要独占一个fabio listen的端口。那是否可以实现多个https服务使用一个fabio端口，并通过host name route呢？fabio支持tcp+sni的route策略。</p>
<p>SNI, 全称Server Name Indication，即服务器名称指示。它是一个扩展的TLS计算机联网协议。该协议允许在握手过程开始时通过客户端告诉它正在连接的服务器的主机名称。这允许服务器在相同的IP地址和TCP端口号上呈现多个证书，也就是允许在相同的IP地址上提供多个安全HTTPS网站（或其他任何基于TLS的服务），而不需要所有这些站点使用相同的证书。</p>
<p>接下来，我们就来看一下如何在fabio中让多个后端https服务共享一个Fabio服务端口(9996)。我们建立两个job：httpsbackend-sni-1和httpsbackend-sni-2。</p>
<pre><code>//httpsbackend-tcp-sni-1.nomad

job "httpsbackend-sni-1" {

... ...

    service {
        name = "httpsbackend-sni-1"
        tags = ["urlprefix-mysite-sni-1.com/ proto=tcp+sni"]
        port = "https"
        check {
          name     = "alive"
          type     = "tcp"
          path     = "/"
          interval = "10s"
          timeout  = "2s"
        }
      }

.... ...

}

//httpsbackend-tcp-sni-2.nomad

job "httpsbackend-sni-2" {

... ...

   task "httpsbackend-sni-2" {
      driver = "docker"
      config {
        image = "bigwhite/httpsbackendservice:v1.0.1"
        port_map {
          https = 7777
        }
        logging {
          type = "json-file"
        }
    }

    service {
        name = "httpsbackend-sni-2"
        tags = ["urlprefix-mysite-sni-2.com/ proto=tcp+sni"]
        port = "https"
        check {
          name     = "alive"
          type     = "tcp"
          path     = "/"
          interval = "10s"
          timeout  = "2s"
        }
      }

.... ...

}

</code></pre>
<p>我们看到与之前的server tag不同的是：这里proto=tcp+sni，即告诉fabio建立sni路由。httpsbackend-sni-2 task与httpsbackend-sni-1不同之处在于其使用image为bigwhite/httpsbackendservice:v1.0.1，为的是能通过https的应答结果，将这两个服务区分开来。</p>
<p>除此之外，我们还看到tag中并不包含端口号了，而是直接采用host name作为路由匹配标识。</p>
<p>创建这两个job：</p>
<pre><code># nomad job run httpsbackend-tcp-sni-1.nomad
==&gt; Monitoring evaluation "af170d98"
    Evaluation triggered by job "httpsbackend-sni-1"
    Allocation "8ea1cc8d" modified: node "7acdd7bc", group "httpsbackend-sni-1"
    Allocation "e16cdc73" modified: node "9e3ef19f", group "httpsbackend-sni-1"
    Evaluation status changed: "pending" -&gt; "complete"
==&gt; Evaluation "af170d98" finished with status "complete"

# nomad job run httpsbackend-tcp-sni-2.nomad
==&gt; Monitoring evaluation "a77d3799"
    Evaluation triggered by job "httpsbackend-sni-2"
    Allocation "32df450c" modified: node "c281658a", group "httpsbackend-sni-2"
    Allocation "e1bf4871" modified: node "7acdd7bc", group "httpsbackend-sni-2"
    Evaluation status changed: "pending" -&gt; "complete"
==&gt; Evaluation "a77d3799" finished with status "complete"

</code></pre>
<p>我们来分别访问这两个服务：</p>
<pre><code># curl -k https://mysite-sni-1.com:9996/
this is httpsbackendservice, version: v1.0.0

# curl -k https://mysite-sni-2.com:9996/
this is httpsbackendservice, version: v1.0.1

</code></pre>
<p>从返回的结果我们看到，通过9996，我们成功暴露出两个不同的https服务。</p>
<h2>五. 小结</h2>
<p>到这里，我们实现了我们的既定目标：</p>
<ol>
<li>
<p>使用nomad实现了工作负载的创建和调度；</p>
</li>
<li>
<p>东西向流量通过consul机制实现；</p>
</li>
<li>
<p>通过fabio实现了http、https(through tcp)、多https(though tcp+sni)的服务暴露和负载均衡。</p>
</li>
</ol>
<p>后续我们将进一步探索基于nomad实现负载的多种场景的升降级操作(滚动、金丝雀、蓝绿部署)、对非host网络的支持（比如weave network)等。</p>
<p>本文涉及到的源码文件在<a href="https://github.com/bigwhite/experiments/tree/master/nomad-demo/part1/jobs">这里</a>可以下载。</p>
<h2>六. 参考资料</h2>
<ol>
<li><a href="https://www.hashicorp.com/blog/resilient-infrastructure-with-nomad-scheduling">使用Nomad构建弹性基础设施：nomad调度</a></li>
<li><a href="https://www.hashicorp.com/blog/resilient-infrastructure-with-nomad-restarting-tasks">使用Nomad构建弹性基础设施：重启任务</a></li>
<li><a href="https://www.hashicorp.com/blog/building-resilient-infrastructure-with-nomad-job-lifecycle">使用Nomad构建弹性基础设施:   job生命周期</a></li>
<li><a href="https://www.hashicorp.com/blog/resilient-infrastructure-with-nomad-fault-tolerance-outage-recovery">使用Nomad构建弹性基础设施：容错和自我修复</a></li>
<li><a href="https://fabiolb.net/ref/">fabio参考指南</a></li>
</ol>
<hr />
<p>我的网课“<a href="https://coding.imooc.com/class/284.html">Kubernetes实战：高可用集群搭建、配置、运维与应用</a>”在慕课网上线了，感谢小伙伴们学习支持！</p>
<p><a href="https://tonybai.com/">我爱发短信</a>：企业级短信平台定制开发专家 https://tonybai.com/<br />
smspush : 可部署在企业内部的定制化短信平台，三网覆盖，不惧大并发接入，可定制扩展； 短信内容你来定，不再受约束, 接口丰富，支持长短信，签名可选。</p>
<p>著名云主机服务厂商DigitalOcean发布最新的主机计划，入门级Droplet配置升级为：1 core CPU、1G内存、25G高速SSD，价格5$/月。有使用DigitalOcean需求的朋友，可以打开这个<a href="https://m.do.co/c/bff6eed92687">链接地址</a>：https://m.do.co/c/bff6eed92687 开启你的DO主机之路。</p>
<p>我的联系方式：</p>
<p>微博：https://weibo.com/bigwhite20xx<br />
微信公众号：iamtonybai<br />
博客：tonybai.com<br />
github: https://github.com/bigwhite</p>
<p>微信赞赏：<br />
<img src="https://tonybai.com/wp-content/uploads/wechat-zanshang-code-512x512.jpg" alt="img{512x368}" /></p>
<p>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。</p>
<p style='text-align:left'>&copy; 2019, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2019/03/30/cluster-management-and-microservice-deployment-and-scheduled-by-nomad/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>官宣：慕课网课程“Kubernetes实战：高可用集群搭建、配置、运维与应用”上线了</title>
		<link>https://tonybai.com/2018/10/17/imooc-course-kubernetes-practice-go-online/</link>
		<comments>https://tonybai.com/2018/10/17/imooc-course-kubernetes-practice-go-online/#comments</comments>
		<pubDate>Wed, 17 Oct 2018 10:28:04 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[aliyun]]></category>
		<category><![CDATA[cloud-native]]></category>
		<category><![CDATA[CNCF]]></category>
		<category><![CDATA[cni]]></category>
		<category><![CDATA[container]]></category>
		<category><![CDATA[controller]]></category>
		<category><![CDATA[dashboard]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[EFK]]></category>
		<category><![CDATA[elastic]]></category>
		<category><![CDATA[ElasticSearch]]></category>
		<category><![CDATA[ELK]]></category>
		<category><![CDATA[event]]></category>
		<category><![CDATA[harbor]]></category>
		<category><![CDATA[heapster]]></category>
		<category><![CDATA[High-Available]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[imooc]]></category>
		<category><![CDATA[ingress]]></category>
		<category><![CDATA[istio]]></category>
		<category><![CDATA[k8s]]></category>
		<category><![CDATA[kubeadm]]></category>
		<category><![CDATA[kubectl]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[label]]></category>
		<category><![CDATA[logging]]></category>
		<category><![CDATA[Master]]></category>
		<category><![CDATA[microservice]]></category>
		<category><![CDATA[Namespace]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[pod]]></category>
		<category><![CDATA[PV]]></category>
		<category><![CDATA[PVC]]></category>
		<category><![CDATA[registry]]></category>
		<category><![CDATA[Service]]></category>
		<category><![CDATA[ServiceMesh]]></category>
		<category><![CDATA[storage]]></category>
		<category><![CDATA[StorageClass]]></category>
		<category><![CDATA[troubleshooting]]></category>
		<category><![CDATA[volume]]></category>
		<category><![CDATA[weave]]></category>
		<category><![CDATA[worker]]></category>
		<category><![CDATA[云原生]]></category>
		<category><![CDATA[云应用]]></category>
		<category><![CDATA[容器]]></category>
		<category><![CDATA[微服务]]></category>
		<category><![CDATA[慕课网]]></category>
		<category><![CDATA[服务]]></category>
		<category><![CDATA[服务治理]]></category>
		<category><![CDATA[服务网格]]></category>
		<category><![CDATA[网课]]></category>
		<category><![CDATA[高可用]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=2644</guid>
		<description><![CDATA[距离我的第一门网课《Kubernetes基础：开启云原生之门》上线已经过去5个多月了，我的实战课《Kubernetes实战：高可用集群搭建、配置、运维与应用》终于在9月27日正式上线了。 一. 课程介绍 《Kubernetes实战：高可用集群搭建、配置、运维与应用》的课程内容与最初课程设计时规划的内容大纲没有太多出入，基本就是根据我最初的想法拟定的内容，这也基本是我这两年学习k8s、积累的k8s实践的路线。整个课程基于kubernetes 1.10.2版本(docker 17.03.2ce)。课程内容大致分为七个部分（与课程主页的课程目录结构稍有差异，但课程内容是一致的）： 第一章 搭建你的第一个Kubernetes集群 本章介绍了一个使用kubeadm引导的Kubernetes集群的搭建和基本配置方法。 1-1: 导学 1-2: 安装准备 1-3: 初始化集群master节点 1-4: 向集群加入worker节点 1-5: 安装dashboard和heapster 1-6: 验证集群安装结果 第二章 Kubernetes集群探索 本章对kubeadm初始化集群的原理进行了讲解，并对已经建立的k8s集群中的各个组件进行详细介绍，包括功用、原理和配置等 2-1: kubeadm init流程揭秘 2-2: kubeadm join流程揭秘 2-3: kubernetes核心组件详解 2-4: kubectl详解 第三章 Kubernetes网络、安全与存储 本章讲解k8s集群的三个难点：网络、安全与存储的概念和运行原理。 3-1：kubernetes集群网络 3-1-1: kubernetes集群的“三个网络” 3-1-2: kubernetes网络的设计要求 3-1-3: kubernetes网络实现 3-1-4: pod网络实现原理 3-1-5: pod网络方案对比 3-1-6: service网络实现原理 3-2: kubernetes集群安全 3-2-1: kube-apiserver安全模型 3-2-2: [...]]]></description>
			<content:encoded><![CDATA[<p>距离我的第一门网课<a href="https://www.imooc.com/learn/978">《Kubernetes基础：开启云原生之门》</a>上线已经过去5个多月了，我的实战课<a href="https://coding.imooc.com/class/chapter/284.html">《Kubernetes实战：高可用集群搭建、配置、运维与应用》</a>终于在9月27日正式上线了。</p>
<p><img src="https://tonybai.com/wp-content/uploads/k8s-practice-frontpage.png" alt="img{512x368}" /></p>
<h3>一. 课程介绍</h3>
<p><img src="https://tonybai.com/wp-content/uploads/k8s-practice-content-1.png" alt="img{512x368}" /></p>
<p><img src="https://tonybai.com/wp-content/uploads/k8s-practice-content-2.png" alt="img{512x368}" /></p>
<p><a href="https://coding.imooc.com/class/chapter/284.html">《Kubernetes实战：高可用集群搭建、配置、运维与应用》</a>的课程内容与最初课程设计时规划的内容大纲没有太多出入，基本就是根据我最初的想法拟定的内容，<strong>这也基本是我这两年学习k8s、积累的k8s实践的路线</strong>。整个课程基于kubernetes 1.10.2版本(<a href="https://tonybai.com/tag/docker">docker</a> 17.03.2ce)。课程内容大致分为七个部分（与课程主页的课程目录结构稍有差异，但课程内容是一致的）：</p>
<p>第一章 搭建你的第一个<a href="https://tonybai.com/tag/kubernetes">Kubernetes集群</a></p>
<p>本章介绍了一个使用<a href="https://tonybai.com/2016/12/30/install-kubernetes-on-ubuntu-with-kubeadm/">kubeadm</a>引导的Kubernetes集群的搭建和基本配置方法。</p>
<ul>
<li>1-1: 导学</li>
<li>1-2: 安装准备</li>
<li>1-3: 初始化集群master节点</li>
<li>1-4: 向集群加入worker节点</li>
<li>1-5: <a href="https://tonybai.com/2017/09/26/some-notes-about-deploying-kubernetes-dashboard-1-7-0/">安装dashboard和heapster</a></li>
<li>1-6: 验证集群安装结果</li>
</ul>
<p>第二章 <a href="https://tonybai.com/2017/01/24/explore-kubernetes-cluster-installed-by-kubeadm/">Kubernetes集群探索</a></p>
<p>本章对kubeadm初始化集群的原理进行了讲解，并对已经建立的k8s集群中的各个组件进行详细介绍，包括功用、原理和配置等</p>
<ul>
<li>2-1: kubeadm init流程揭秘</li>
<li>2-2: kubeadm join流程揭秘</li>
<li>2-3: kubernetes核心组件详解</li>
<li>2-4: <a href="https://tonybai.com/2018/06/14/the-authentication-and-authorization-of-kubectl-when-accessing-k8s-cluster/">kubectl</a>详解</li>
</ul>
<p>第三章 Kubernetes网络、安全与存储<br />
本章讲解k8s集群的三个难点：网络、安全与存储的概念和运行原理。</p>
<p>3-1：kubernetes<a href="https://tonybai.com/2017/01/17/understanding-flannel-network-for-kubernetes/">集群网络</a></p>
<ul>
<li>3-1-1: kubernetes集群的“三个网络”</li>
<li>3-1-2: kubernetes网络的设计要求</li>
<li>3-1-3: kubernetes网络实现</li>
<li>3-1-4: pod网络实现原理</li>
<li>3-1-5: pod网络方案对比</li>
<li>3-1-6: service网络实现原理</li>
</ul>
<p>3-2: <a href="https://tonybai.com/2018/06/14/the-authentication-and-authorization-of-kubectl-when-accessing-k8s-cluster/">kubernetes集群安全</a></p>
<ul>
<li>3-2-1: kube-apiserver安全模型</li>
<li>3-2-2: 传输安全</li>
<li>3-2-3: <a href="https://tonybai.com/2016/11/25/the-security-settings-for-kubernetes-cluster/">身份验证</a></li>
<li>3-2-4: 授权</li>
<li>3-2-5: 准入控制</li>
</ul>
<p>3-3 kubernets集群存储</p>
<ul>
<li>3-3-1: Volume</li>
<li>3-3-2: <a href="https://tonybai.com/2016/11/07/integrate-kubernetes-with-ceph-rbd/">PV和PVC</a></li>
<li>3-3-3: StorageClass和动态PV供给</li>
<li>3-3-4: Kubernetes存储模型</li>
</ul>
<p>第四章 <a href="https://tonybai.com/2017/05/15/setup-a-ha-kubernetes-cluster-based-on-kubeadm-part1/">高可用Kubernetes集群</a>搭建方案<br />
本章介绍了什么是高可用k8s集群，并给出了一个可行的高可用Kubernetes集群的搭建方案。</p>
<ul>
<li>4-1: 什么是高可用Kubernetes集群</li>
<li>4-2: 高可用Kubernetes集群方案</li>
</ul>
<p>第五章 Kubernetes集群常见运维操作</p>
<p>本章讲解了Kubernetes集群的基本运维操作，包括node管理、service、pod管理、日志查看等。并讲解了面对k8s集群问题时如何做troubleshooting。</p>
<ul>
<li>5-1: 管理Node与Label</li>
<li>5-2: 管理Namespace、Service和Pod</li>
<li>5-3: <a href="https://tonybai.com/2017/10/16/out-of-node-resource-handling-in-kubernetes-cluster/">计算资源管理</a></li>
<li>5-4: 查看事件和容器日志</li>
<li>5-5: 常用TroubleShooting方法</li>
</ul>
<p>第六章 Kubernetes支撑<a href="https://www.cncf.io/">云原生应用</a>开发案例<br />
本章讲解了Kubernetes集群的应用：支撑云原生应用开发。并通过实际操作讲解了镜像仓库、集中日志以及云应用治理框架的搭建和使用。</p>
<ul>
<li>6-1: Kubernetes与云原生应用</li>
<li>6-2: <a href="https://tonybai.com/2017/12/08/deploy-high-availability-harbor-on-kubernetes-cluster/">高可用私有镜像仓库搭建</a></li>
<li>6-3: <a href="https://tonybai.com/2018/06/13/setup-efk-on-kubernetes-1-10-3-in-the-hard-way/">基于ElasticSearch Stack搭建集群Logging设施</a></li>
<li>6-4: <a href="https://tonybai.com/2018/01/03/an-intro-of-microservices-governance-by-istio/">基于istio service mesh实现服务治理</a></li>
</ul>
<p>第七章 课程回顾与总结</p>
<h3>二. 做网课目的与课程思路</h3>
<p>当初接下慕课商务的这门课主要是出于两个目的：</p>
<ul>
<li>通过这门课程对自己的k8s学习和实践做一个阶段性的系统总结</li>
<li>尝试一下网课这个“新鲜”事物</li>
</ul>
<p>现在看来，当初这两个“目的”都实现了。但是录制网课的确是件很“辛苦”的事情，不知道多少的夜晚和周末都留给了“网课资料编写和录制”。尤其是Kubernetes这个主题，讲起来“顾虑”很多：</p>
<ul>
<li>
<p>和编程语言课不同，Kubernetes平台是个复杂的平台，外延生态很庞大。k8s概念多，如果不把概念和原理交待清楚、讲透彻，直接就上手操作，那样学习后，对k8s的理解仍然不会很深刻，很多问题仍然无法自己去解决，尤其是中高级阶段。 这就导致很多小伙伴认为课程概念讲解“有些多”；</p>
</li>
<li>
<p>生产环境中k8s集群有大有小，使用目的也是大不相同，安装方式也是有很多种(官方就列了10多种)，所在的网络环境以及使用的pod网络插件也是区别很大，遇到的问题更是千差万别，这里在准备 课程时也是思来想去，无法覆盖所有生产环境的所有情况。最后决定使用kubeadm搭建一个4节点的集群(使用weave network plugin)，可能能更好的满足初学者的需求，学员们更容易获取搭建这样一个 k8s环境所需的资源。而关于课程中实际操作部分重点集中在前面的k8s搭建、集群探索以及后面的k8s对云应用支撑的环节。所以如果小伙伴们的环境与课程不同，可以在课程后提问，我会尽量第一时间、细致的回答各位的问题。</p>
</li>
<li>
<p>关于时长，我在课程里尽量做到没有”废话“。现在的网课多根据“时长”定价（虽然不赞同，但是目前也没有一个更好的量化课程质量的方法）：比如10个小时以上可能就会定到399元，但是不足10小时，可能就在199元这个价位。<strong>于是我努力地将课程做到了“199”这个价位上了</strong>。对于真正想学习k8s的小伙伴们，这也许是一个“好消息”:)。</p>
</li>
</ul>
<h3>三. 课程小结</h3>
<p>Kubernetes还在快速不断地演进！我个人觉得学完本门课程也仅仅是“Kubernetes实践之路”的一个开始而已！应用上云的趋势已经不可逆转，对于云应用开发人员来说，<strong>了解和学习Kubernetes就像当年单机时代开发人员要去了解PC操作系统一样重要</strong>！希望本门课程能给更多的开发者带去帮助！</p>
<p>下面是课程的自制海报，欢迎转发:)</p>
<p><img src="https://tonybai.com/wp-content/uploads/k8s-practice-with-qr-and-text.png" alt="img{512x368}" /></p>
<hr />
<p><a href="https://tonybai.com/">我爱发短信</a>：企业级短信平台定制开发专家 https://tonybai.com/<br />
smspush : 可部署在企业内部的定制化短信平台，三网覆盖，不惧大并发接入，可定制扩展； 短信内容你来定，不再受约束, 接口丰富，支持长短信，签名可选。</p>
<p>著名云主机服务厂商DigitalOcean发布最新的主机计划，入门级Droplet配置升级为：1 core CPU、1G内存、25G高速SSD，价格5$/月。有使用DigitalOcean需求的朋友，可以打开这个<a href="https://m.do.co/c/bff6eed92687">链接地址</a>：https://m.do.co/c/bff6eed92687 开启你的DO主机之路。</p>
<p>我的联系方式：</p>
<p>微博：https://weibo.com/bigwhite20xx<br />
微信公众号：iamtonybai<br />
博客：tonybai.com<br />
github: https://github.com/bigwhite</p>
<p>微信赞赏：<br />
<img src="https://tonybai.com/wp-content/uploads/wechat-zanshang-code-512x512.jpg" alt="img{512x368}" /></p>
<p>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。</p>
<p style='text-align:left'>&copy; 2018 &#8211; 2020, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2018/10/17/imooc-course-kubernetes-practice-go-online/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>TB一周萃选[第9期]</title>
		<link>https://tonybai.com/2018/02/11/9th-issue-of-the-tech-weekly-carefully-chosen-by-tonybai/</link>
		<comments>https://tonybai.com/2018/02/11/9th-issue-of-the-tech-weekly-carefully-chosen-by-tonybai/#comments</comments>
		<pubDate>Sun, 11 Feb 2018 05:41:08 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[artificial-intelligence]]></category>
		<category><![CDATA[browser]]></category>
		<category><![CDATA[Ceph]]></category>
		<category><![CDATA[circuitbreaker]]></category>
		<category><![CDATA[cloud-native]]></category>
		<category><![CDATA[CNCF]]></category>
		<category><![CDATA[Codereview]]></category>
		<category><![CDATA[conduit]]></category>
		<category><![CDATA[Context]]></category>
		<category><![CDATA[deep-learning]]></category>
		<category><![CDATA[EBS]]></category>
		<category><![CDATA[egress]]></category>
		<category><![CDATA[GCP]]></category>
		<category><![CDATA[GeoffreyHinton]]></category>
		<category><![CDATA[gerrit]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Go-1.10-Release-Party]]></category>
		<category><![CDATA[Go1.10]]></category>
		<category><![CDATA[Go1.6]]></category>
		<category><![CDATA[Go1.7]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[GoogleCloudPlatform]]></category>
		<category><![CDATA[HTTP2]]></category>
		<category><![CDATA[ingress]]></category>
		<category><![CDATA[istio]]></category>
		<category><![CDATA[k8s]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[metrics]]></category>
		<category><![CDATA[middleware]]></category>
		<category><![CDATA[NFS]]></category>
		<category><![CDATA[Package]]></category>
		<category><![CDATA[PR]]></category>
		<category><![CDATA[Redhat]]></category>
		<category><![CDATA[rook]]></category>
		<category><![CDATA[S3]]></category>
		<category><![CDATA[ServiceMesh]]></category>
		<category><![CDATA[SSE]]></category>
		<category><![CDATA[tracing]]></category>
		<category><![CDATA[websocket]]></category>
		<category><![CDATA[中华民族]]></category>
		<category><![CDATA[云原生]]></category>
		<category><![CDATA[云存储]]></category>
		<category><![CDATA[亲情]]></category>
		<category><![CDATA[人工智能]]></category>
		<category><![CDATA[传统]]></category>
		<category><![CDATA[充电]]></category>
		<category><![CDATA[分布式存储]]></category>
		<category><![CDATA[华夏]]></category>
		<category><![CDATA[反向传播]]></category>
		<category><![CDATA[回家]]></category>
		<category><![CDATA[安全]]></category>
		<category><![CDATA[密码管理]]></category>
		<category><![CDATA[度量]]></category>
		<category><![CDATA[微服务]]></category>
		<category><![CDATA[性能优化]]></category>
		<category><![CDATA[春节]]></category>
		<category><![CDATA[春运]]></category>
		<category><![CDATA[服务治理]]></category>
		<category><![CDATA[浏览器]]></category>
		<category><![CDATA[深度学习]]></category>
		<category><![CDATA[胶囊理论]]></category>
		<category><![CDATA[节日]]></category>
		<category><![CDATA[过年]]></category>

		<guid isPermaLink="false">http://tonybai.com/?p=2552</guid>
		<description><![CDATA[本文是首发于个人微信公众号的文章“TB一周萃选[第9期]”的归档。 亲情犹如一江剪不断的春水，流动的是游子心中永远的思念；亲情犹如一丘数不尽的细沙，沉淀的是长年堆积的牵挂；亲情犹如夜空中那颗北斗，指引的是那迷路的羔羊回家的方向。忙碌了一年，该回家了，给心放个假，带上媳妇带上你的娃，回家看看那年迈的爸妈，出发！ &#8212; 改编自网络 此时此刻，很多人刚刚踏上了春节回家的旅途，有些人更是已经叩开了家的大门。每逢中国传统佳节-春节，令世界瞩目并为之瞠目结舌的中国式人口大迁移就会发生一次：几亿人熬夜刷票并不辞辛劳地携着夫/妻儿女，经由多种交通工具，跨越高山大河，不远千百里，战胜种种“囧况”，只为一个目的：在春节前回到那个充满熟悉味道的家乡。 这种在一个文明延续5000多年未中断的民族中发生的全民行为让西方社会感到十分不解，甚至指责这是对资源的一种浪费；并且也有国内的人发出类似不和谐的声音。但是它依然在发生着，每年都在发生，形式有些许变化，但剧情大体雷同。 曾经有国内外学者对中国特有的春节大迁徙的原因进行研究和分析，并给出了各种专业化的理由。但在我看来，对现代人来说，回家过年，是一种心灵的相互充电! 而且是充电7天，“通话”一整年。 对于一年到头在外奔波劳碌的人们来说，只有回家，才能真实地触摸到自己的“根”，才能切切实实地体会这种归属感，才能在一定程度上纾解那些在工作的城市中涵盖不了的人生寄托。在这种归属感中，哪怕只是获得片刻的身心安宁，也是一种极为重要的精神能量的充电；而对于守候在家乡的父母或者孩童儿，你的回家，让他们将近一年的期盼终于有了一个圆满的结果，这同样为下一个365天的期盼周期提供了强大的动力和希望。 如果非要给这种行为找个理由，那我要说这就是由一个体内延绵数千年的中华民族血脉的中国人的基因所决定的。 一、一周文章精粹 1. Go 1.10发布Party 自从Go 1.6开始，每逢偶数版本（一般在每年2、3月发布），Gopher社区都会举办庆祝Release的全球Party。在中国农历春节到来之际，也恰逢Go最新版本Go 1.10即将发布之时，Go wiki发布了Go 1.10 Release Party的Schedule和相关资料。截至目前，已经有15个Party已经list到页面上，活动从2月15号一直延续到3月份。 Go 1.10发布Party官网页面 Go 1.10 Release Note Draft The State of Go 1.10 2. 避免或减少对Go context Value的使用 context包最初诞生于Google公司内部，并在Google内部项目大量使用。context在golang/x中孵化了多年，并得到了很多开源项目的使用，尤其是一些使用了”middleware”模式的项目中，于是在Go 1.7发布时，context包正式加入Go标准库。context加入后，可谓既带来魔力，亦带来了争议，甚至有人将其视为具有“病毒”属性，一旦使用，便可轻易传染到项目中代码的各个角落。 Go开发者、培训师Jon Calhoun也在个人网站上撰写了一篇文章，来告诫大家Go context value的一些缺陷，建议大家避免或减少对Go context Value的使用，并给出自己的替代方案。其主要理由是：context.WithValue和Context.Value的使用让我们失去了编译器对类型安全性的检查。 文章链接：“Pitfalls of context values and how to avoid or mitigate [...]]]></description>
			<content:encoded><![CDATA[<p>本文是首发于<a href="https://mp.weixin.qq.com/mp/qrcode?scene=10000005&amp;size=102&amp;__biz=MzIyNzM0MDk0Mg==&amp;mid=2247483848&amp;idx=1&amp;sn=a3cd9182a2b2d3716623cc2c43d59f37&amp;send_time=">个人微信公众号</a>的文章<strong>“TB一周萃选[第9期]”</strong>的归档。</p>
<p><img src="http://tonybai.com/wp-content/uploads/weekly-issues/9th-issue/go-home-during-spring-festival.jpg" alt="img{512x368}" /></p>
<blockquote>
<p>亲情犹如一江剪不断的春水，流动的是游子心中永远的思念；亲情犹如一丘数不尽的细沙，沉淀的是长年堆积的牵挂；亲情犹如夜空中那颗北斗，指引的是那迷路的羔羊回家的方向。忙碌了一年，该回家了，给心放个假，带上媳妇带上你的娃，回家看看那年迈的爸妈，出发！  &#8212;  改编自网络</p>
</blockquote>
<p>此时此刻，很多人刚刚踏上了春节回家的旅途，有些人更是已经叩开了家的大门。每逢中国传统佳节-<a href="https://en.wikipedia.org/wiki/Chinese_New_Year">春节</a>，令世界瞩目并为之瞠目结舌的中国式人口大迁移就会发生一次：几亿人熬夜刷票并不辞辛劳地携着夫/妻儿女，经由多种交通工具，跨越高山大河，不远千百里，战胜种种“囧况”，只为一个目的：在春节前回到那个充满熟悉味道的家乡。</p>
<p>这种在一个文明延续5000多年未中断的民族中发生的<strong>全民行为</strong>让西方社会感到十分不解，甚至指责这是对资源的一种浪费；并且也有国内的人发出类似不和谐的声音。但是<strong>它依然在发生着，每年都在发生</strong>，形式有些许变化，但剧情大体雷同。</p>
<p>曾经有国内外学者对中国特有的春节大迁徙的原因进行研究和分析，并给出了各种专业化的理由。但在我看来，对现代人来说，回家过年，是一种<strong>心灵的相互充电</strong>!  而且是<strong>充电7天，“通话”一整年</strong>。</p>
<p>对于一年到头在外奔波劳碌的人们来说，只有回家，才能真实地触摸到自己的“根”，才能切切实实地体会这种归属感，才能在一定程度上纾解那些在工作的城市中涵盖不了的人生寄托。在这种归属感中，哪怕只是获得片刻的身心安宁，也是一种极为重要的精神能量的充电；而对于守候在家乡的父母或者孩童儿，你的回家，让他们将近一年的期盼终于有了一个圆满的结果，这同样为下一个365天的期盼周期提供了强大的动力和希望。</p>
<p>如果非要给这种行为找个理由，那我要说这就是由一个体内延绵数千年的中华民族血脉的中国人的基因所决定的。</p>
<p><img src="http://tonybai.com/wp-content/uploads/weekly-issues/9th-issue/chinese-dragon.jpg" alt="img{512x368}" /></p>
<h2>一、一周文章精粹</h2>
<h3>1. Go 1.10发布Party</h3>
<p>自从<a href="http://tonybai.com/2016/02/21/some-changes-in-go-1-6/">Go 1.6</a>开始，每逢偶数版本（一般在每年2、3月发布），Gopher社区都会举办庆祝Release的<a href="https://twitter.com/hashtag/goreleaseparty">全球Party</a>。在中国农历春节到来之际，也恰逢Go最新版本Go 1.10即将发布之时，Go wiki发布了<a href="https://github.com/golang/go/wiki/Go-1.10-Release-Party">Go 1.10 Release Party</a>的Schedule和相关资料。截至目前，已经有15个Party已经list到页面上，活动从2月15号一直延续到3月份。</p>
<ul>
<li><a href="https://github.com/golang/go/wiki/Go-1.10-Release-Party">Go 1.10发布Party官网页面</a></li>
<li><a href="https://tip.golang.org/doc/go1.10">Go 1.10 Release Note Draft</a></li>
<li><a href="https://speakerdeck.com/campoy/the-state-of-go-1-dot-10">The State of Go 1.10</a></li>
</ul>
<h3>2. 避免或减少对Go context Value的使用</h3>
<p>context包最初诞生于Google公司内部，并在Google内部项目大量使用。context在golang/x中孵化了多年，并得到了很多开源项目的使用，尤其是一些使用了”middleware”模式的项目中，于是在<a href="http://tonybai.com/2016/06/21/some-changes-in-go-1-7/">Go 1.7发布</a>时，context包正式加入Go标准库。context加入后，可谓既带来魔力，亦带来了争议，甚至有人将其视为<a href="https://faiface.github.io/post/context-should-go-away-go2/">具有“病毒”属性</a>，一旦使用，便可轻易传染到项目中代码的各个角落。</p>
<p>Go开发者、培训师Jon Calhoun也在个人网站上撰写了一篇文章，来告诫大家Go context value的一些缺陷，建议大家避免或减少对Go context Value的使用，并给出自己的替代方案。其主要理由是：context.WithValue和Context.Value的使用让我们失去了编译器对类型安全性的检查。</p>
<p>文章链接：<a href="https://www.calhoun.io/pitfalls-of-context-values-and-how-to-avoid-or-mitigate-them">“Pitfalls of context values and how to avoid or mitigate them in Go”</a></p>
<h3>3. 来自Google Cloud Platform的12条有关用户账号、授权和密码管理的最佳实践</h3>
<p>对于许多开发者来说，账户管理是一个黑暗的角落，没有得到足够的重视。来自Google Cloud Platform的解决方案专家Ian Maddox给我们带来了12条有关此方面的最佳实践，包括：区分用户标识与用户账号、允许用户更改用户名、用户ID大小写敏感、两步验证等。</p>
<p><img src="http://tonybai.com/wp-content/uploads/weekly-issues/9th-issue/user-account-and-password.jpg" alt="img{512x368}" /></p>
<p>文章链接：<a href="https://cloudplatform.googleblog.com/2018/01/12-best-practices-for-user-account.html">“12 best practices for user account, authorization and password management”</a></p>
<h3>4. AI界网红-深度学习之父Geoffrey Hinton的传奇学术生涯</h3>
<p>这几年最火爆的人工智能技术就是深度学习，可以说当下的主流人工智能就是深度学习，而深度学习的理论基石就是反向传播。和当代物理学类似，最新的计算机应用实际上也是在消化几十年前就已经建立的理论，这不：反向传播就是Geoffrey Hinton与同事David Rumelhart、Ronald Williams在1986年发布的成果，Geoffrey Hinton也因此被誉为深度学习之父。Geoffrey Hinton花了30年在AI前沿的研究，在今天终于开花结果。不过这位现在AI奠基人并没有就此停歇，去年他还提出了“<a href="https://arxiv.org/abs/1710.09829">胶囊理论</a>”，不过要彻底理解他的理论，不知道AI应用界还要花多久。下面这篇文章是“多伦多生活”上发表的一篇有关Geoffrey Hinton的传奇学术生涯的新闻稿，我们可以通过它一瞥AI超级明星的学术人生。</p>
<p><img src="http://tonybai.com/wp-content/uploads/weekly-issues/9th-issue/the-father-of-deeplearning-geoffrey-hinton.jpg" alt="img{512x368}" /><br />
图：Geoffrey Hinton</p>
<p>文章链接：<a href="https://torontolife.com/tech/ai-superstars-google-facebook-apple-studied-guy/">“深度学习之父Geoffrey Hinton的传奇学术生涯”</a></p>
<h3>5. Go项目在github上接受PR了</h3>
<p>go语言自身的开发一直是在google内部的平台上，github上的golang项目仅仅是其一个mirror。在这之前，golang项目在github上是拒绝pr的，contributor必须注册google的开发账号才能为go语言本身做贡献，这种门槛显然有些高。近期Go项目作出了对社区更为友好的举动：<a href="https://go-review.googlesource.com/c/go/+/92995">允许在github上直接提交PR</a>。不过代码的review依旧是在google原平台上，github上提交的pr将被GerritBot自动同步到Go team的Gerrit上进行code review。不过这已经是一个不错的开端了。估计会吸引更多开发者为Go做contribution。</p>
<p>文章链接：<br />
  * <a href="https://go-review.googlesource.com/c/go/+/92995">“doc: remove Pull Request note in README.md”</a><br />
  * <a href="https://github.com/golang/go/wiki/GerritBot">“pr流程”</a></p>
<h2>二、一周资料分享</h2>
<h3>1. istio微服务教程 by Redhat</h3>
<p>下一代微服务平台日益火爆，比如：<a href="http://tonybai.com/2018/01/03/an-intro-of-microservices-governance-by-istio/">istio</a>、<a href="https://conduit.io/">conduit</a>等。近期Redhat开源了一套istio微服务教程，主要是for java microservice，但感觉对其他语言开发的微服务也适用。教程使用的是<a href="https://istio.io/">istio</a>最新发布的<a href="https://github.com/istio/istio/releases/tag/0.5.0">0.5.0版本</a>，底层使用的是redhat自身的oc平台(openshift)，但替换成<a href="http://tonybai.com/tag/kubernetes">kubernetes</a>应该很容易。教程包含的内容还是很全面的，针对包括metrics、tracing、routerule管理、fault injection、retry&amp;timeout、mirroring traffic、access control、rate limiting、circuit breaker、egress等常见的微服务框架治理机制都提供了demo实例。</p>
<p>资料分享链接：<a href="https://github.com/redhat-developer-demos/istio-tutorial">Istio Tutorial for Java Microservices</a></p>
<h2>三、一周项目推荐</h2>
<h3>1. rook：致力于让存储服务成为云原生平台上的“头等”服务</h3>
<p>2018年1月30日，云原生<a href="https://www.cncf.io/">cncf组织</a>下又增加了一位新成员:<a href="https://rook.io/">rook项目</a>，由于刚入行，其与linkerd、coredns同样处于Inception级别。rook是什么？它解决了哪些问题呢？</p>
<p>如今在Kubernetes上部署的应用在使用存储服务时，多使用k8s集群外提供的外部存储服务。在公有云上，使用较多的是诸如<a href="https://aws.amazon.com/cn/ebs/">EBS</a>、<a href="https://aws.amazon.com/s3/">S3</a>等；在定制云/私有云中，使用的则是NFS、<a href="http://tonybai.com/tag/ceph">Ceph</a>或更为传统的存储解决方案，如下图所示：</p>
<p><img src="http://tonybai.com/wp-content/uploads/weekly-issues/9th-issue/before-using-rook.png" alt="img{512x368}" /><br />
图：使用rook前</p>
<p>Rook存在的意义就是将存储服务移入集群内部，让那些依赖存储服务的应用可以无缝地使用这些服务，这样一来，整个云原生集群环境就可以脱离厂商依赖（比如对amazon、google cloud platform的依赖），实现整体的可移植了，无论是公有云还是私有云。</p>
<p><img src="http://tonybai.com/wp-content/uploads/weekly-issues/9th-issue/after-using-rook.png" alt="img{512x368}" /><br />
图：使用rook后</p>
<p>可以说，Rook<strong>让存储服务成为云原生平台上的“头等”服务</strong>，与其他应用服务一样。</p>
<p>那Rook究竟是什么呢？Rook不是一个像ceph那样的分布式共享存储系统。rook的考虑是：与其花费几年甚至十几年实现一个成熟的、久经考验的分布式存储系统，到不如帮助现有的已经十分成熟的、久经沙场的存储系统更方便的被云原生环境中的应用所使用，比如：<a href="https://ceph.com/">ceph</a>。于是rook通过将那些专有存储服务管理员的日常操作自动化：包括引导启动、配置、伸缩、升级、迁移、灾难恢复、监控、资源管理，将存储服务包装为云原生应用，无缝运行在云原生环境上，目前主要是在Kubernetes上。</p>
<p><img src="http://tonybai.com/wp-content/uploads/weekly-issues/9th-issue/rook-architecture.png" alt="img{512x368}" /><br />
图：rook架构</p>
<p>Rook的出现，迅速得到了来自Redhat、ceph开发者的支持，社区也在日益壮大。目前其最新版本为v0.6.2，按计划在2018年中旬发布第一个production-ready的正式版。</p>
<p>项目地址：<a href="https://github.com/rook/rook">Rook</a></p>
<h2>四、一周图书推荐</h2>
<h3>1.《High Performance Browser Networking》</h3>
<p><img src="http://tonybai.com/wp-content/uploads/weekly-issues/9th-issue/book-high-performance-browser-networking.jpg" alt="img{512x368}" /></p>
<p>Ilya Grigorik是Google性能优化工程师，他在2013出版的这本<a href="https://book.douban.com/subject/21866396/">《High Performance Browser Networking》</a>堪称当代Web性能调优的圣经。该书以调优为核心，从网络基础(101)讲起，然后深入探讨了无线和移动网络的工作机制。最后，揭示了HTTP 协议的底层细节，同时详细介绍了HTTP 2.0、 XHR、SSE、WebSocket、WebRTC 和DataChannel 等现代浏览器新增的具有革命性的新能力。该书无论是对前端开发，还是后端网络服务开发设计人员都是大有裨益的。</p>
<p>更重要的是该书当时所讲述的诸多浏览器协议技术，比如：HTTP2.0、WebSocket、SSE在如今已经成为标准，并广泛应用于生产实践中。</p>
<p>图书链接：<br />
   英文版：<a href="https://book.douban.com/subject/21866396/">《High Performance Browser Networking》</a><br />
   中文版：<a href="https://book.douban.com/subject/25856314/">《Web性能权威指南》</a><br />
   免费版：<a href="https://hpbn.co/">《High Performance Browser Networking》</a></p>
<hr />
<p>著名云主机服务厂商DigitalOcean发布最新的主机计划，入门级Droplet配置升级为：1 core CPU、1G内存、25G高速SSD，价格5$/月。有使用DigitalOcean需求的朋友，可以打开这个<a href="https://m.do.co/c/bff6eed92687">链接地址</a>：https://m.do.co/c/bff6eed92687 开启你的DO主机之路。</p>
<p>我的联系方式：</p>
<p>微博：http://weibo.com/bigwhite20xx<br />
微信公众号：iamtonybai<br />
博客：tonybai.com<br />
github: https://github.com/bigwhite</p>
<p>微信赞赏：<br />
<img src="http://tonybai.com/wp-content/uploads/wechat-zanshang-code-512x512.jpg" alt="img{512x368}" /></p>
<p>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作</p>
<p style='text-align:left'>&copy; 2018, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2018/02/11/9th-issue-of-the-tech-weekly-carefully-chosen-by-tonybai/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TB一周萃选[第6期]</title>
		<link>https://tonybai.com/2018/01/20/6th-issue-of-the-tech-weekly-carefully-chosen-by-tonybai/</link>
		<comments>https://tonybai.com/2018/01/20/6th-issue-of-the-tech-weekly-carefully-chosen-by-tonybai/#comments</comments>
		<pubDate>Sat, 20 Jan 2018 06:22:58 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[CDN]]></category>
		<category><![CDATA[Channel]]></category>
		<category><![CDATA[cloud-native]]></category>
		<category><![CDATA[cloudflare]]></category>
		<category><![CDATA[colly]]></category>
		<category><![CDATA[DigitalOcean]]></category>
		<category><![CDATA[DNS]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[droplet]]></category>
		<category><![CDATA[FaaS]]></category>
		<category><![CDATA[GC]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[justforfun]]></category>
		<category><![CDATA[kubeflow]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[Lambda]]></category>
		<category><![CDATA[mesos]]></category>
		<category><![CDATA[ncurses]]></category>
		<category><![CDATA[nil]]></category>
		<category><![CDATA[openai]]></category>
		<category><![CDATA[pivotal]]></category>
		<category><![CDATA[re:Invent]]></category>
		<category><![CDATA[swarm]]></category>
		<category><![CDATA[TCP]]></category>
		<category><![CDATA[tview]]></category>
		<category><![CDATA[Twelve-Factor-App]]></category>
		<category><![CDATA[云原生]]></category>
		<category><![CDATA[人工智能]]></category>
		<category><![CDATA[人工智能标准化白皮书2018版]]></category>
		<category><![CDATA[大数据]]></category>
		<category><![CDATA[奋斗]]></category>
		<category><![CDATA[孙正义]]></category>
		<category><![CDATA[容器]]></category>
		<category><![CDATA[小米]]></category>
		<category><![CDATA[微服务]]></category>
		<category><![CDATA[敏捷]]></category>
		<category><![CDATA[爬虫]]></category>
		<category><![CDATA[软银]]></category>

		<guid isPermaLink="false">http://tonybai.com/?p=2532</guid>
		<description><![CDATA[本文是首发于个人微信公众号的文章“TB一周萃选[第6期]”的归档。 图：第6期封面 凡事欲其成功，必须付出代价——奋斗。 — 美国作家 爱默生 每期挑选“封面图”都是一件颇为“费工夫”的事情，本期的封面图来自于一个投资界大V发送的微博内容，因为当我第一眼看到这幅图片时，感觉它颇为契合我当时的心境。 “未来的一年里，连睡觉都是浪费时间”这句话的最原始的出处在哪里我还没有查到，但最近与这句话“勾搭”上关系的是小米公司，因为坊间传闻小米公司要开启上市计划了。但小米公司绝对不是这句话的“始作俑者”，因为我查到著名的投资人孙正义先生在2017中旬举行的SoftBank World大会中的一次演讲中也提到过：”未来让我激动，感觉睡觉都是在浪费时间”这一同义的说法。 先不管人们对这句话是否感同身受，实际情况是当今人们用于睡觉的时间真的是越来越少了。已经成功的人为了追求更大的成功或让企业长期利于不败之地而殚精竭虑，他们不能睡；正走在通往成功道路上的奋斗者们，加班加点，兢兢业业，亲力亲为，他们不愿睡；大多安于现状、不愿折腾的打工族们则贪恋红尘，吃喝唱K、刷剧吃鸡、答题聊天的时间还不够呢，哪忍心放下手机或电脑去呼呼大睡呢，他们不舍得睡。 由此看来，似乎这个“网红句子”在不同人内心中的含义是可以不同的。但无论怎样，我敢肯定的是这幅图会让那些新的一年中心中目标满满并欲为之奋斗的人振奋不已。大家都说刚刚新年伊始，其实已经过去了半个多月了，时间真的不等人：学习要速度，发展要速度，增长要速度，那么多工作和目标等待着你去完成，抓紧这本应该是睡眠的时间，努力奋斗吧。 图：2018.1.18雾凇景观(沈阳) 一、一周文章精粹 1. AWS Lambda正式宣布对Go的支持 在2017年末举办的AWS re:Invent大会上，AWS的技术人员就剧透了Lambda将对Go提供正式支持。本月15号，AWS官方正式宣布了Lambda对Go的支持，并在github上发布了aws-lambda-go的1.0.0版本。现在全世界的gopher们就可以使用自己心仪的语言来编写自己的第一个Function as a Service例子了。 文章链接：“Announcing Go Support for AWS Lambda” 2. Cloudflare公司的TCP协议栈深入理解系列 Cloudflare是世界知名的CDN服务商，这些年Cloudflare公司的主要技术栈也转移到了Go语言，包括其DNS系统等。Cloudflare在TCP/IP网络方面有了较为深入的理解，其研发人员经常在其官方blog发表有关互联网协议方面的技术文章，这里将其中几篇抽取汇总出来，形成“TCP协议栈深入理解系列”，包括： The story of one latency spike This is strictly a violation of the TCP specification SYN packet handling in the wild 3. 高性能Go语言编程 印象中，高性能Go编程这个topic，大胡子Dave Cheney在几个技术大会上都讲过，Dave自己关于这方面的认知也在演化，这次在QCon大会上的演讲应该他对Go高性能编程的最新理解。 [...]]]></description>
			<content:encoded><![CDATA[<p>本文是首发于<a href="https://mp.weixin.qq.com/mp/qrcode?scene=10000005&amp;size=102&amp;__biz=MzIyNzM0MDk0Mg==&amp;mid=2247483848&amp;idx=1&amp;sn=a3cd9182a2b2d3716623cc2c43d59f37&amp;send_time=">个人微信公众号</a>的文章<strong>“TB一周萃选[第6期]”</strong>的归档。</p>
<p><img src="http://tonybai.com/wp-content/uploads/weekly-issues/6th-issue/tb-6th-issue-cover.jpg" alt="img{512x368}" /><br />
图：第6期封面</p>
<blockquote>
<p>凡事欲其成功，必须付出代价——奋斗。<br />
                         — 美国作家 爱默生</p>
</blockquote>
<p>每期挑选“封面图”都是一件颇为“费工夫”的事情，本期的封面图来自于一个投资界大V发送的微博内容，因为当我第一眼看到这幅图片时，感觉它<strong>颇为契合我当时的心境</strong>。</p>
<p><strong>“未来的一年里，连睡觉都是浪费时间”</strong>这句话的最原始的出处在哪里我还没有查到，但最近与这句话“勾搭”上关系的是小米公司，因为坊间传闻小米公司要开启上市计划了。但小米公司绝对不是这句话的“始作俑者”，因为我查到著名的投资人孙正义先生在2017中旬举行的<a href="https://www.huxiu.com/article/206194.html">SoftBank World大会中的一次演讲</a>中也提到过：”未来让我激动，感觉睡觉都是在浪费时间”这一同义的说法。</p>
<p>先不管人们对这句话是否感同身受，实际情况是当今人们用于睡觉的时间真的是越来越少了。已经成功的人为了追求更大的成功或让企业长期利于不败之地而殚精竭虑，<strong>他们不能睡</strong>；正走在通往成功道路上的奋斗者们，加班加点，兢兢业业，亲力亲为，<strong>他们不愿睡</strong>；大多安于现状、不愿折腾的打工族们则贪恋红尘，吃喝唱K、刷剧吃鸡、答题聊天的时间还不够呢，哪忍心放下手机或电脑去呼呼大睡呢，<strong>他们不舍得睡</strong>。</p>
<p>由此看来，似乎这个“网红句子”在不同人内心中的含义是可以不同的。但无论怎样，我敢肯定的是这幅图会让那些新的一年中心中目标满满并欲为之奋斗的人振奋不已。大家都说刚刚新年伊始，其实已经过去了半个多月了，时间真的不等人：学习要速度，发展要速度，增长要速度，那么多工作和目标等待着你去完成，抓紧这本应该是睡眠的时间，努力<strong>奋斗</strong>吧。</p>
<p><img src="http://tonybai.com/wp-content/uploads/weekly-issues/6th-issue/wusong-20180118-at-neusoft-park.jpg" alt="img{512x368}" /><br />
图：2018.1.18雾凇景观(沈阳)</p>
<h2>一、一周文章精粹</h2>
<h3>1. <a href="https://aws.amazon.com/lambda">AWS Lambda</a>正式宣布对Go的支持</h3>
<p>在2017年末举办的<a href="https://reinvent.awsevents.com/">AWS re:Invent大会</a>上，AWS的技术人员就剧透了Lambda将对<a href="http://tonybai.com/tag/go">Go</a>提供正式支持。本月15号，AWS官方<a href="https://aws.amazon.com/cn/blogs/compute/announcing-go-support-for-aws-lambda/">正式宣布了Lambda对Go的支持</a>，并在github上发布了<a href="https://github.com/aws/aws-lambda-go">aws-lambda-go</a>的<a href="https://github.com/aws/aws-lambda-go/releases/tag/v1.0.0">1.0.0版本</a>。现在全世界的gopher们就可以使用自己心仪的语言来编写自己的第一个<a href="https://en.wikipedia.org/wiki/Function_as_a_service">Function as a Service</a>例子了。</p>
<p><img src="http://tonybai.com/wp-content/uploads/weekly-issues/6th-issue/aws-lambda-support-go.png" alt="img{512x368}" /></p>
<p>文章链接：<a href="https://aws.amazon.com/cn/blogs/compute/announcing-go-support-for-aws-lambda/">“Announcing Go Support for AWS Lambda”</a></p>
<h3>2. Cloudflare公司的TCP协议栈深入理解系列</h3>
<p>Cloudflare是世界知名的CDN服务商，这些年Cloudflare公司的主要技术栈也转移到了Go语言，包括其DNS系统等。Cloudflare在TCP/IP网络方面有了较为深入的理解，其研发人员经常在其官方blog发表有关互联网协议方面的技术文章，这里将其中几篇抽取汇总出来，形成“TCP协议栈深入理解系列”，包括：</p>
<ul>
<li><a href="https://blog.cloudflare.com/the-story-of-one-latency-spike/">The story of one latency spike</a> </li>
<li><a href="https://blog.cloudflare.com/this-is-strictly-a-violation-of-the-tcp-specification/">This is strictly a violation of the TCP specification</a></li>
<li><a href="https://blog.cloudflare.com/syn-packet-handling-in-the-wild">SYN packet handling in the wild</a></li>
</ul>
<h3>3. 高性能Go语言编程</h3>
<p>印象中，高性能Go编程这个topic，大胡子<a href="https://dave.cheney.net/">Dave Cheney</a>在几个技术大会上都讲过，Dave自己关于这方面的认知也在演化，这次在QCon大会上的演讲应该他对Go高性能编程的最新理解。</p>
<p>文章链接：<a href="https://www.infoq.com/presentations/go-programming-language">“High performance Go by Dave Cheney”</a></p>
<h3>4. 为什么Go中会有nil channel?</h3>
<p><a href="https://github.com/campoy/">Francesc Campoy</a>是Go core team前成员，他的<a href="https://github.com/campoy/justforfunc/">“just for fun”</a>系列播客在广大Gopher圈里十分受欢迎，其最新一期<a href="https://medium.com/justforfunc/why-are-there-nil-channels-in-go-9877cc0b2308">“为什么Go中会有nil channel?”</a>讲解了nil channel在实际编码中的妙用。</p>
<p><img src="http://tonybai.com/wp-content/uploads/weekly-issues/6th-issue/nil-channel-demo.png" alt="img{512x368}" /></p>
<p>文章链接：<a href="https://medium.com/justforfunc/why-are-there-nil-channels-in-go-9877cc0b2308">为什么Go中会有nil channel?</a></p>
<h3>5. 将Kubernetes集群扩展到2500个节点</h3>
<p>容器与Kubernetes等容器管理基础设施的出现改变的不仅仅企业的业务应用架构和开发模式，对近两年火热的人工智能、机器学习也是一种赋能。当前Kubernetes支撑的人工智能/机器学习环境是目前一个流行的趋势，比如发布不久的<a href="https://github.com/google/kubeflow">Kubeflow</a>。不过2015年末的成立的<a href="https://blog.openai.com/scaling-kubernetes-to-2500-nodes/">openai组织</a>则早就将Kubernetes运用于人工智能领域的研究，截止目前该组织运行管理的Kubernetes集群已经达到2500个节点。本周openai发表文章讲述了他们是如何将Kubernetes集群管理的节点数量扩展到2500个的，他们的下一个目标是5000个节点。</p>
<p>文章链接：<a href="https://blog.openai.com/scaling-kubernetes-to-2500-nodes/">“Scaling Kubernetes to 2,500 Nodes”</a></p>
<h3>6、Kubernetes的引力</h3>
<p>2017年，Kubernetes战胜了swarm和mesos，成为容器管理和服务编排方面的事实标准。</p>
<p><img src="http://tonybai.com/wp-content/uploads/weekly-issues/6th-issue/kubernetes-trends.png" alt="img{512x368}" /></p>
<p>“Kubernetes引力”这篇文章从标准、容器管理编排、适配多云平台、适用于分布式系统部署等多方面论述Kubernetes对IT世界的改变。</p>
<p>文章链接：<a href="https://www.softwaredaily.com/#/post/5a5a2387f43c8d000457a110">“The Gravity of Kubernetes”</a></p>
<h2>二、一周资料分享</h2>
<h3>1. 人工智能标准化白皮书（2018版）</h3>
<p>2018年1月18日，在国家人工智能标准化总体组、专家咨询组成立大会上，大会发布了“人工智能标准化白皮书2018版”，对人工智能技术的历史、发展现状及趋势、人工智能的标准体系以及国内外标准化的现状做了系统的阐述。</p>
<p>人工智能标准化白皮书2018:  链接: https://pan.baidu.com/s/1qZTPyCc 密码: x3qn</p>
<h2>三、一周项目推荐</h2>
<h3>1. tview</h3>
<p><a href="https://github.com/rivo/tview">tview</a>是用纯Go语言编写的一款终端UI组件库，用于实现基于terminal的文本式交互界面。类似于传统的C语言<a href="https://www.gnu.org/software/ncurses/">ncurses库</a>。tview提供了许多widget，并且有对应的demo代码对应，使用起来十分方便：</p>
<ul>
<li>输入框（包括密码字段输入、下拉选择、选择框、按钮）</li>
<li>可导航的多色文字视图</li>
<li>导航表视图</li>
<li>可选列表</li>
<li>Flexbox和页面布局</li>
<li>模态消息窗口</li>
</ul>
<p><img src="http://tonybai.com/wp-content/uploads/weekly-issues/6th-issue/tview-demos.jpg" alt="img{512x368}" /></p>
<p>项目地址：<a href="https://github.com/rivo/tview">tview</a></p>
<h3>2. colly</h3>
<p>数据在移动互联网时代以及即将到来的AI时代都是具有核心价值的。数据的获取途径之一就是通过爬虫工具获取公共数据，并作为数据价值挖掘的输入。colly就是一款用于编写爬虫工具的框架，它使用Go语言实现，提供优雅、简洁的API接口、高效的性能、并发爬取管理、缓存、robots.txt支持等功能，同时colly还提供了详尽的<a href="http://go-colly.org/docs/">使用文档</a>以及丰富的<a href="https://github.com/gocolly/colly/tree/master/_examples">examples</a>。</p>
<p><img src="http://tonybai.com/wp-content/uploads/weekly-issues/6th-issue/colly-demo.png" alt="img{512x368}" /></p>
<p>项目地址：<a href="https://github.com/gocolly/colly">colly</a></p>
<h2>四、一周图书推荐</h2>
<h3>1.《迁移到云原生应用架构》</h3>
<p><img src="http://tonybai.com/wp-content/uploads/weekly-issues/6th-issue/migrating-to-cloud-native-application-architectures-cover.png" alt="img{512x368}" /><br />
图：Migrating to Cloud-Native Application Architectures封面</p>
<p>就好比00后被称为是互联网时代“原住民”一样，近几年的一些应用架构演化模式被称为“云原生”应用(cloud-native application)，换句好理解的话来说，就是这些应用天生就是应该跑在云上的，而且具有诸多契合云计算平台的特征，而不仅仅是简单地将传统单体应用从单机挪到虚拟机或容器中部署。</p>
<p>云原生（Cloud Native）这个概念最初是由<a href="https://pivotal.io/">Pivotal公司</a>的 <a href="http://www.mattstine.com/">Matt Stine</a>在 2013年提出的，是他对多年架构和咨询经验进行总结后的一个成果。2015年，他操刀编写了“Migrating to Cloud-Native Application Architectures”，也就是这里推荐的这本短小的开源书。</p>
<p>这本书的脉络十分清晰，首先Matt告诉我们什么是云原生架构以及为什么要用云原生架构。不过Matt并没有给出精确的云原生的定义，而是告诉我们云原生应用架构具有哪些特征，包括：”<a href="https://12factor.net/zh_cn/">twelve factor app</a>“、微服务、自服务敏捷架构、基于API写作等；接下来Matt告诉我们如果企业要接纳云原生架构，应该如何从文化、组织和技术等三个方面进行变革；最后的一个小章节则是迁移到云原生应用的实操mini手册。</p>
<p>随着<a href="http://tonybai.com/tag/kubernetes">kubernetes</a>、容器进一步发展以及对应用的进一步赋能，人们对云原生应用的认识还在进一步深刻中，pivotal在<a href="https://pivotal.io/cn/cloud-native">官网</a>上对cloud-native的概念做了进一步总结归纳，建议结合这本书一并学习一下。</p>
<p><img src="http://tonybai.com/wp-content/uploads/weekly-issues/6th-issue/pivotal-diagram-of-cloud-native.png" alt="img{512x368}" /><br />
图：Pivotal对云原生概念进一步阐述</p>
<p>图书链接：<br />
    <a href="https://jimmysong.io/migrating-to-cloud-native-application-architectures">《迁移到云原生应用架构》中译版</a><br />
    <a href="https://content.pivotal.io/ebooks/migrating-to-cloud-native-application-architectures">《Migrating to Cloud-Native Application Architectures》</a></p>
<hr />
<p>著名云主机服务厂商DigitalOcean于1月17日<a href="https://blog.digitalocean.com/new-droplet-plans/">发布了其新的主机计划(New Droplet Plan)</a>，此次发布是对其原有主机计划的优化，其中入门级Droplet的内存容量从512M升级为1G，SSD磁盘空间从20G升级到25G，但价格不变，依旧是5$/月。如果你已经使用了DigitalOcean服务，可以到后台手动进行Resize以享受增容后的主机性能。如果您还没有使用DigitalOcean，可以去看看DO的vps plan是否满足你的需求。 链接地址：https://m.do.co/c/bff6eed92687</p>
<p><img src="http://tonybai.com/wp-content/uploads/weekly-issues/6th-issue/digitalocean-new-standard-plans-table.png" alt="img{512x368}" /><br />
图：New Plan的价格表</p>
<hr />
<p>我的联系方式：</p>
<p>微博：http://weibo.com/bigwhite20xx<br />
微信公众号：iamtonybai<br />
博客：tonybai.com<br />
github: https://github.com/bigwhite</p>
<p>微信赞赏：<br />
<img src="http://tonybai.com/wp-content/uploads/wechat-zanshang-code-512x512.jpg" alt="img{512x368}" /></p>
<p>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。</p>
<p style='text-align:left'>&copy; 2018, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2018/01/20/6th-issue-of-the-tech-weekly-carefully-chosen-by-tonybai/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
