Tech

IntelliJ IDEA 集成 DeepSeek 辅助编程

在人工智能辅助编程工具日益普及的今天,DeepSeek 以其卓越的性能和实惠的价格在开发者社区中迅速走红。作为一名从 DeepSeek v1 就开始使用的资深用户,我见证了它在代码生成、问题解答和开发建议等方面的持续进步。当时为什么选择用它?一方面,与 ChatGPT 相比,DeepSeek 不仅提供了更具竞争力的 API 定价策略,其网页版对话应用更是完全免费。另一方面,经过与国内其他同类产品的深入对比测试,我发现 DeepSeek 的回复更加简洁精准,特别适合技术场景下的使用需求。 随着 DeepSeek-R1 版本的发布,其性能指标在多个基准测试中均表现出显著优势。本文将详细介绍如何将这一强大的 AI 模型集成到 IntelliJ IDEA 中,为您的开发工作流程注入新的活力。 环境准备 在开始集成之前,请确保您的开发环境满足以下要求: IntelliJ IDEA 2023 或更高版本 (注:较早版本的 IDEA 可能无法完全支持 codeGPT 插件的 UI 显示) 下载地址:IntelliJ IDEA 官方下载页面 安装 codeGPT 插件 codeGPT 是一个功能强大的插件,它充当了 IDE 与 AI 模型之间的桥梁。通过它,开发者可以直接在 IDE 中调用 DeepSeek 的服务。 安装步骤: 打开 IntelliJ IDEA 进入插件市场(File -> Settings -> Plugins) 搜索 “codeGPT” 并安装 重启 IDE 完成安装 获取 DeepSeek API 密钥 访问 DeepSeek 开发者平台:https://platform.

抽象泄露法则

在 AI 时代,开发效率大幅提升。某团队借助 AI 辅助开发,仅用 5 分钟便完成了一个新功能的开发,初看运行正常。然而,在某些特定场景下,功能却出现了意料之外的问题。团队花了半天时间排查,才发现问题的根源深藏于底层实现之中——本以为可以忽略的细节,最终却成了最大的坑。 另一边,某系统突发线上故障,业务开发人员求助平台开发人员,期待快速定位问题。然而,平台开发人员查看后表示:“底层代码没有问题,业务侧再看看。” 业务开发团队只好继续摸索,试图在复杂的调用链与抽象层中找到线索。原本清晰分工的技术栈,在关键时刻变得模糊不清,底层的复杂性不可避免地泄露出来。 软件世界就是一层抽象套着另一层抽象的千层饼,就好像 HTTP 协议下有 TCP、TCP 下有 IP,每一层抽象都声称自己是完美的:“你无需关注在我之下的任何细节”。 但事实却是,所有抽象必定泄露。而当抽象泄露时,就像要从 AI 生成的 1000 行代码里找到那个错误——事情非常棘手,但我们别无选择。 早在 2002 年,程序员 Joel Spolsky 就敏锐地发现了这类现象,并将它们总结为:“抽象泄露法则”。 译文如下: 抽象泄露法则 作者:Joel Spolsky 日期:2002年11月11日,星期一 互联网工程中有一项关键的魔法,你每天都在依赖它。这种魔法发生在TCP协议中,TCP是互联网的基础构建模块之一。 TCP是一种可靠的数据传输方式。我的意思是:如果你通过网络使用TCP发送一条消息,它将会到达目的地,并且不会出现乱码或损坏。 我们使用TCP来做很多事情,比如获取网页和发送电子邮件。TCP的可靠性确保了每一封来自东非诈骗者的激动人心的电子邮件都能以完美的状态送达。哦,真是令人欣喜。 相比之下,还有一种称为IP的数据传输方式,它是不可靠的。没有人保证你的数据会到达目的地,而且数据在到达之前可能会被搞乱。如果你用IP发送一堆消息,不要惊讶只有一半的消息到达,而且其中一些消息的顺序与发送时的顺序不同,还有一些消息可能被替换为其他内容,或许是可爱的猩猩宝宝图片,或者更可能只是一堆无法阅读的垃圾,看起来像台湾垃圾邮件的主题行。 这里的神奇之处在于:TCP是建立在IP之上的。换句话说,TCP必须通过一种不可靠的工具来可靠地发送数据。 为了说明这为什么是魔法,请考虑以下道德上等效但有些荒谬的现实世界场景。 想象一下,我们有一种将百老汇演员送到好莱坞的方式,方法是把他们塞进车里,然后开车穿越全国。有些车会撞毁,可怜的演员因此丧生。有时演员在路上喝醉了,剃了光头或纹了鼻环,结果变得太丑无法在好莱坞工作。而且,演员们到达的顺序通常与他们出发的顺序不同,因为他们都走了不同的路线。现在想象一种名为“好莱坞快线”的新服务,它保证将演员送到好莱坞,并确保他们(a)到达,(b)按顺序到达,(c)状态完好。神奇之处在于,好莱坞快线没有任何其他方法可以运送演员,除了将他们塞进车里并开车穿越全国这种不可靠的方式。好莱坞快线的工作原理是检查每个演员是否完好无损地到达,如果没有,就打电话给总部,要求发送该演员的同卵双胞胎代替。如果演员到达的顺序不对,好莱坞快线会重新排列他们。如果一架飞往51区的大型UFO在内华达州的高速公路上坠毁,导致道路无法通行,所有走那条路的演员都会通过亚利桑那州重新安排路线,而好莱坞快线甚至不会告诉加利福尼亚的电影导演发生了什么。对他们来说,演员只是比平时到得慢了一点,他们甚至从未听说过UFO坠毁事件。 这大致就是TCP的魔法。它是计算机科学家喜欢称之为“抽象”的东西:一种对底层复杂事物的简化。事实证明,许多计算机编程工作都涉及构建抽象。什么是字符串库?它是一种假装计算机可以像操作数字一样轻松操作字符串的方式。什么是文件系统?它是一种假装硬盘并不是一堆可以存储比特的旋转磁性盘片,而是一个由文件夹嵌套文件夹组成的层次系统,其中包含由一或多个字节串组成的单个文件。 回到TCP。为了简单起见,我之前撒了一个小谎,现在可能有些人已经气得冒烟了,因为这个谎言让你抓狂。我说TCP保证你的消息会到达。实际上,它并不保证。如果你的宠物蛇咬断了连接到你电脑的网络电缆,导致没有IP数据包可以通过,那么TCP对此无能为力,你的消息也不会到达。如果你对公司的系统管理员态度粗鲁,他们惩罚你,把你连接到一个过载的集线器上,那么只有部分IP数据包能通过,TCP仍然可以工作,但一切都会变得非常慢。 这就是我所说的“抽象泄漏”。TCP试图提供一个对底层不可靠网络的完整抽象,但有时,网络会通过抽象泄漏暴露出来,你会感受到那些抽象无法完全保护你免受的影响。这只是我称之为“抽象泄漏法则”的一个例子: 所有非平凡的抽象,在某种程度上,都是有泄漏的。 抽象会失效。有时是小问题,有时是大问题。泄漏会出现。事情会出错。当你使用抽象时,这种情况无处不在。以下是一些例子。 即使是遍历一个大的二维数组这样简单的事情,如果你水平遍历而不是垂直遍历,性能可能会有天壤之别,这取决于“木纹的方向”——一个方向可能会导致比另一个方向多得多的页面错误,而页面错误是很慢的。即使是汇编程序员也被允许假装他们有一个大的平坦地址空间,但虚拟内存意味着它实际上只是一个抽象,当发生页面错误时,某些内存访问会比其他的多花很多纳秒,这时抽象就出现了泄漏。 SQL语言旨在抽象出查询数据库所需的过程步骤,而是让你只需定义你想要的内容,并让数据库自行找出查询的过程步骤。但在某些情况下,某些SQL查询比其他逻辑上等效的查询慢数千倍。一个著名的例子是,在某些SQL服务器上,如果你指定“where a=b and b=c and a=c”,查询速度会比只指定“where a=b and b=c”快得多,尽管结果集是相同的。你本不应该关心过程,只需关心规范。但有时抽象会泄漏,导致性能极差,你不得不拿出查询计划分析器,研究它哪里出了问题,并找出如何让你的查询运行得更快。 尽管像NFS和SMB这样的网络库让你可以像对待本地文件一样对待远程机器上的文件,但有时连接会变得非常慢或中断,文件就不再表现得像本地文件一样,作为程序员,你必须编写代码来处理这种情况。“远程文件与本地文件相同”的抽象出现了泄漏。这里有一个针对Unix系统管理员的具体例子。如果你将用户的主目录放在NFS挂载的驱动器上(一种抽象),而用户创建了.forward文件以将所有电子邮件转发到其他地方(另一种抽象),当新邮件到达时,如果NFS服务器宕机,邮件将不会被转发,因为.forward文件将无法找到。抽象中的泄漏实际上导致了一些邮件被丢弃。 C++字符串类本应让你假装字符串是一等数据。它们试图抽象出字符串的复杂性,让你感觉它们像整数一样容易操作。几乎所有的C++字符串类都重载了+操作符,因此你可以写s + “bar"来进行连接。但你知道吗?无论它们多么努力,地球上没有任何一个C++字符串类能让你输入"foo” + “bar”,因为C++中的字符串字面量始终是char*,而不是字符串。抽象出现了泄漏,而语言本身不允许你修补它。(有趣的是,C++的演变历史可以被描述为试图修补字符串抽象泄漏的历史。为什么他们不能在语言本身中添加一个原生的字符串类,这让我一时难以理解。) 而且,下雨时你也不能开得太快,尽管你的车有雨刷、头灯、车顶和暖气,这些都让你不必关心下雨的事实(它们抽象了天气),但瞧,你必须担心打滑(在英国称为“水上漂”),有时雨太大,你看不清前方,所以你只能在雨中开得更慢,因为天气永远无法被完全抽象掉,这就是抽象泄漏法则的作用。 抽象泄漏法则之所以成问题,原因之一是它意味着抽象并没有像预期那样真正简化我们的生活。当我培训某人成为C++程序员时,如果我能永远不必教他们关于char和指针运算的知识,那将是非常好的。如果我能直接跳到STL字符串,那将是非常好的。但有一天他们会写"foo" + “bar"这样的代码,然后真正奇怪的事情会发生,那时我将不得不停下来教他们所有关于char的知识。或者有一天,他们会尝试调用一个Windows API函数,该函数的文档显示它有一个OUT LPTSTR参数,直到他们学习了char*、指针、Unicode、wchar_t和TCHAR头文件等知识,他们才能理解如何调用它。所有这些泄漏都会暴露出来。 在教某人COM编程时,如果我能只教他们如何使用Visual Studio向导和所有代码生成功能,那将是非常好的。但如果出现问题,他们将完全不知道发生了什么,也不知道如何调试和恢复。我将不得不教他们所有关于IUnknown、CLSID、ProgID等的知识……哦,真是让人头疼! 在教某人ASP.NET编程时,如果我能只教他们可以双击某些东西,然后编写在用户点击这些内容时在服务器上运行的代码,那将是非常好的。事实上,ASP.NET抽象了处理点击超链接(<a>)的HTML代码和处理点击按钮的代码之间的区别。问题是:ASP.NET的设计者需要隐藏一个事实,即在HTML中,没有办法通过超链接提交表单。他们通过生成几行JavaScript代码并将onclick处理程序附加到超链接上来实现这一点。然而,抽象出现了泄漏。如果最终用户禁用了JavaScript,ASP.NET应用程序将无法正常工作,如果程序员不理解ASP.NET抽象了什么,他们将完全不知道哪里出了问题。 抽象泄漏法则意味着,每当有人提出一个花哨的新代码生成工具,声称能让我们变得非常高效时,你会听到很多人说:“先学会手动操作,然后再用花哨的工具来节省时间。”那些假装抽象某些东西的代码生成工具,像所有抽象一样,都是有泄漏的,而唯一能有效处理这些泄漏的方法是学习抽象的工作原理以及它们抽象了什么。因此,抽象节省了我们工作的时间,但它们并没有节省我们学习的时间。 这一切意味着,尽管我们有了越来越高级的编程工具和越来越好的抽象,但成为一名熟练的程序员却变得越来越难。

应用层数据分布路由算法

应用层数据分布路由算法主要用于分布式系统中,将数据或请求分配到多个节点(服务器、存储设备或服务实例)上,以实现负载均衡、高可用性和扩展性。常见的有: 哈希取模(Modulo Hashing)、随机路由 (Random Routing)、一致性哈希(Consistent Hashing)等等。 随机路由 (Random Routing) 原理:随机选择一个节点处理请求。 特点: 简单直观,但不能保证均匀分布。 不适合高负载系统,因为可能导致数据倾斜。 应用:用于初步负载均衡或测试场景。 哈希取模(Modulo Hashing) 原理:使用简单的哈希函数对节点数量取模,将请求分配到相应节点。 公式:节点 = Hash(Key) % N,其中 N 是节点数量。 特点:简单高效,易于实现。 缺点:节点增减时,所有数据都需要重新分配,无法满足动态性要求。 应用:适用于小规模系统或节点数固定的场景。 一致性哈希(Consistent Hashing) 原理:将节点和数据映射到一个逻辑环上,数据存储在与其哈希值最接近的节点中。 特点: 高动态性:节点增减时,仅影响邻近的节点,减少数据迁移量。 负载均衡:通过虚拟节点均衡数据分布。 应用: 分布式缓存(如 Memcached、Redis)。 分布式存储(如 Cassandra、Amazon Dynamo)。 微服务负载均衡。 一致性哈希算法实现 一致性Hash首先构建一个Hash 环的结构。环的大小是 0 到2^32-1,也就是无符号整型的取值范围,0 和最后一个 2^32-1 首尾相连,构成一个 Hash 环。将每个缓存服务节点 hash值放到环上。每次一次进行服务器查找路由计算的时候,都是根据key 的hash 值顺时针查找距离它最近的服务器节点。通过这种方式,key 不变的情况下找到的总是相同的服务器。但是,Hash 值是一个随机值,把一个随机值放到一个环上以后,可能是不均衡的,也就是某两个服务器节点在环上的距离可能很近,而和其它的服务器节点距离很远。这会导致有些服务负载压力特别大,有些服务器的负载压力特别小。在实践中,需要使用虚拟节点对方法进行改进,把一个服务节点放到环上时,把它虚拟成200个虚拟节点,然后把 200 个虚拟节点随机放到环上。key 依然是按照顺时针查找距离它最近的虚拟节点,再根据映射关系找到真正的物理节点。 Java 代码实现如下: public class Consistent { SortedMap<Long, PhysicalNode> ring; int virtualNodeCount; public Consistent(int virtualNodeCount) { ring = new TreeMap(); this.

AI 笔记

如何找落地场景 从最熟悉的领域入手 让 AI 学习最厉害员工的能力,再让 ta 辅助其他员工,实现降本增效 找 【文本进,文本出】的场景 别求大而全。将任务拆解,先解决小任务、小场景(小切口、大纵深) 通俗原理 通过上文,猜测下一个词出现的概率。 大模型阅读了大量人类说过的所有话(训练),就是机器学习 把一串 token 后面跟着的不同 token 的概率存入神经网络,保存的数据就是参数,也叫权重 当我们给它若干 token,大模型就能算出概率最高的下一个 token 是什么。这就是生成,也叫推理 用生成的 token,再加上上文,就能继续生成下一个 token。以此类推,生成更多文字 如何用好 AI? 数字神经网络和人脑的生物神经网络,在数学原理上是一样的。 ——OpenAI 首席科学家 Ilya Sutskever 所以,把 AI 当人看!!!和人怎么相处就和 AI 怎么相处。 使用 AI 的几种模式 Embedding AI(少) AI Copilot(协助) AI Agent(代理) 从上往下,AI 参与处理的任务越多。 AI 相关的编程基本是 Python 语言。 安装 OpenAI pip3 install --upgrade openai 大模型里面的角色 System Role:主要是定义系统的行为规范和全局设置。 Assistant Role:主要负责与用户的交互,根据用户的输入生成响应。 这两种角色在构建对话系统时是互补的,共同决定了系统的整体行为和用户体验。 LangChain 里面的 LLM 模块和 ChatModel LLM:通常用于生成单个文本输出,适合一次性提示和响应的场景。 ChatModel:专门用于处理对话,能够记住对话历史并生成连贯的回复,适合构建多轮对话系统。 框架对比 Llamaindex:主要用于构建和管理向量数据库,特别适合文档检索和知识库管理。 Semantic Kernel:专注于构建对话系统,支持多轮对话和上下文管理,适合构建复杂的对话应用。 LangChain:全面的框架,支持链式处理和多种模型,适合构建多样化的语言模型应用。 Replicate Replicate 是一个云端 AI 模型运行平台,它允许用户通过云端 API 直接运行机器学习模型,非专业人士也能上手。

数据库的动态列

动态列的几种设计思路 在需求开发过程中,我们有时会遇到一种场景:某个具体业务中的属性是动态的。在理想情况下,我们可以使用穷举法对所有可能的属性进行分析,然后进行分类,最终形成一套解决方案。然而,现实往往是骨感的,Leader和客户通常不会给我们这个时间。因此,我们需要探讨一些更为实际的解决方案。 一、使用数据库DDL进行动态创建 优点: 操作简单,只需通过SQL管理即可实现。 缺点: 不同情况下的动态字段增加会导致表结构膨胀。 在已有数据的表中修改字段容易导致锁表,影响性能。 二、使用数据库预留字段 优点: 与数据库无关,对业务侵入性小。 缺点: 扩展性差,超出预留字段范围后如何处理新字段? 可读性差,预留字段通常为attr1、attr2等,影响字段的可读性。 性能较低,为兼容多种数据类型,预留字段通常采用较长的文本数据类型存储,影响数据库性能。 三、使用数据库中的JSON数据类型 优点: 使用简单,绝大多数编程语言都支持JSON操作,方便快捷。 对于MySQL或PostgreSQL等数据库,已原生支持JSON字段,可基于JSON进行扩展查询。 JSON采用key:value形式存储数据,可避免字段可读性差的问题,通过规范命名提高可读性。 扩展性高,增加或删除字段实现简单,直接移除key即可,不影响表性能。 缺点: JSON字段查询操作与普通字段稍有差异,有一定复杂度。 JSON字段的索引性能有待提高。 四、使用NoSQL数据库 优点: 采用MongoDB等JSON数据库,可以快速扩展。 专业数据存储,查询等性能可针对优化,性能高。 缺点: 需要一定的学习成本。 综上所述,第一种和第二种方案若非必要,不建议采用。第三种方案在中小项目中能应对绝大多数需求。如果存储的数据较多且性能要求较高,可以考虑采用第四种方案或第三、四种方案相结合。 支持动态列的数据库 MariaDB 通过创建BLOB列(最大64k?),可以使用mariadb-dynamic-columns实现动态列。 示例: CREATE TABLE items ( id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, name varchar(100) NOT NULL, attributes BLOB ); 插入数据时使用特定函数(COLUMN_CREATE)指定动态列的数据结构,key/value形式: INSERT INTO items (name, attributes) VALUES ('MariaDB t-shirt', COLUMN_CREATE('colour','blue', 'size','XXL')), ('MariaDB t-shirt', COLUMN_CREATE('colour','blue', 'size','XL')), ('Samsung Galaxy S5', COLUMN_CREATE('colour','white', 'OS', 'Android', 'type', 'phone')), ('Samsung Galaxy Pro 3', COLUMN_CREATE('colour','white', 'size',8, 'OS', 'Android', 'resolution','1920x1200', 'type','tablet')); 查询时使用COLUMN_JSON函数,返回JSON格式的数据: SELECT name AS Item, COLUMN_JSON(attributes) AS 'Dynamic Columns' FROM items LIMIT 1; 使用COLUMN_LIST函数列举列中包含的属性,如colour、size: SELECT name AS Item, COLUMN_LIST(attributes) AS 'Attribute Names' FROM items; 查询动态列中具体的某个属性,如colour: SELECT name AS Item, COLUMN_GET(attributes, 'colour' AS CHAR) AS Colour FROM items; PostgreSQL 支持JSON数据类型,相比普通text文本字段类型,JSON数据类型强制要求列中每个存储的值都符合JSON格式规则。

多租户

多租户架构概述与实现 多租户(Multi-tenancy) 是一种软件架构模式,允许多个客户(租户)共享同一个应用实例和底层资源,同时保障租户数据的隔离与安全。租户可以是企业、部门或个人用户。其目标是在优化资源利用效率的同时,满足租户对个性化、安全性和成本效益的需求。 多租户的背景与优势 背景 云计算的普及:随着云计算技术的发展,SaaS(软件即服务)模式迅速崛起,多租户架构成为共享资源和优化成本的关键技术。 资源利用效率需求:通过在同一物理或逻辑服务器上运行多个租户应用,提高资源利用率并降低运营成本。 个性化和隔离需求:满足租户定制化的同时,确保数据安全与隔离。 降低运维成本:多租户架构显著减少了软件升级与补丁管理的复杂性。 优势 低成本:通过共享资源,显著降低基础设施和维护费用。SaaS多租户软件通常以订阅形式提供,租户分担运营成本。 可伸缩性:租户可根据需求灵活扩展,只需调整订阅配置。 无代码定制化:无需复杂的开发,租户即可通过配置满足特定业务需求。 持续更新与维护:软件提供商统一管理更新与补丁,租户自动获得改进,无需额外操作。 提高生产率:租户可专注于核心业务,无需管理基础设施或软件。 多租户架构的实现方式 根据隔离程度和成本,不同场景下的多租户实现方式如下: 1. 共享数据库 + 共享架构 所有租户共享一个数据库实例与数据库架构,租户数据通过租户标识(如租户ID)区分。 优点: 成本低:资源利用率高,节约硬件与运维成本。 开发简单:实现复杂度较低。 适合中小规模租户:支持批量操作。 缺点: 安全性较低:需严格控制租户间的数据隔离。 扩展性有限:租户增长可能引发性能瓶颈。 适用场景:小型SaaS应用,租户间数据隔离需求较低。 2. 独立数据库 + 共享架构 每个租户拥有独立的数据库,但共享数据库架构。 优点: 数据隔离性好:提升安全性。 扩展性强:可独立扩展租户数据库。 缺点: 成本较高:需分配单独数据库实例。 运维复杂度提升:需管理多个数据库实例。 适用场景:中型SaaS应用,数据隔离需求高。 3. 独立数据库 + 独立架构 每个租户拥有独立的数据库与架构,支持更高的定制化。 优点: 高度隔离:数据、性能、定制化完全独立。 灵活性高:满足复杂业务需求。 缺点: 成本高:需为每个租户单独配置资源。 开发与运维复杂度高:架构需逐一维护。 适用场景:大型企业级应用,少量租户但数据敏感且需求复杂。 4. 容器化隔离 通过容器技术(如Docker),为每个租户提供独立的容器化服务。 优点: 部署灵活:每个容器的环境可独立配置。 高扩展性:便于弹性伸缩。 强隔离性:容器内外环境相互独立。 缺点: 运维复杂:需管理容器编排工具(如Kubernetes)。 成本:资源分配灵活性可能引发一定浪费。 适用场景:需要高度隔离和动态扩展的中大型应用。 特殊技术:命名空间与多租户 Linux命名空间 Linux命名空间是一种操作系统层面的资源隔离技术,可以将全局资源划分为命名空间范围内的资源。命名空间隔离涵盖主机名、用户权限、文件系统、网络、进程等,支撑了容器技术(如Docker)。 命名空间通过为每个租户创建独立的资源视图来实现隔离。与Cgroups(控制组)结合使用时,可以进一步限制每个租户对CPU、内存和I/O的使用,从而实现资源的公平分配。例如,网络命名空间可以为每个租户分配独立的虚拟网络接口和IP地址,进而避免资源争夺。 在多租户架构中,Linux命名空间的典型应用包括:

Prompt 框架模版

Crispe Matt Nigh 的 CRISPE Framework,比较适合用于编写 prompt 模板。CRISPE 分别代表以下含义: CR: Capacity and Role(能力与角色)。你希望 ChatGPT 扮演怎样的角色。 I:Insight(洞察力),背景信息和上下文(坦率的说我觉得用Context 更好)。 S: Statement(指令),你希望 ChatGPT 做什么。 P:Personality(个性),你希望 ChatGPT 以什么风格或方式回答你。 E:Experiment(尝试),要求 ChatGPT 为你提供多个答案。 以下是这几个参数的例子: Step Example Capacity and Role Act as an expert on software development on the topic of machine learning frameworks, and an expert blog writer. 把你想象成机器学习框架主题的软件开发专家,以及专业博客作者。 Insight The audience for this blog is technical professionals who are interested in learning about the latest advancements in machine learning.

Kafka 总结

consumer 是推还是拉? https://kafka.apache.org/documentation/#design_pull kafka 生产者端生成消息推送(push)到 broker,消费者端从 broker 拉取(pull)消息。 统一采用 pull 的方式? boker 从生产者 pull 消息。在生产者数量庞大的场景下,broker 需要管理维护很多的关系,简直是梦魇。所以采用的是生产者往 broker push 消息。 统一采用 push 的方式? broker 往 consumer push 消息。在 consumer 多样化的场景下,如果生产者的生产速率远远大于消费者,broker 控制不好,push 会造成 consumer 不堪重负。反之,由 consumer 根据自身处理速率来决定何时从 broker 拉取消息,会更好。采用 pull 的弊端在于,如果 broker 没有消息,那么就会空转,这可以通过在调用 poll 接口时传入等待时间阻塞或者传入批次数据包大小来等待阻塞。 kafka 的 ack 机制 客户端连接到 leader broker 上,发送消息之后,等待或不等待 leader broker 的 ack(是否等待取决于参数request.required.acks 配置)。比如: 客户端设置 acks=0,客户端不作任何等待,即使消息没有写入 kafka 集群。 客户端设置 acks=1,客户端会等待 Leader 副本成功写入后返回的确认,但如果 Leader 副本在消息被同步到其他副本之前崩溃,消息可能会丢失。 客户端设置 acks=all 或 acks=-1参数,leader 在接收到客户端的消息之后,先写入日志文件,然后往同步副本(ISR)发送数据,等所有的 follower 都确认消息写入成功后,leader 再给客户端发送 ack 确认。

Docker 使用

通过 Docker 命令行工具与 Docker Daemon 进程通讯使用。 使用步骤 安装 Docker 到宿主机(物理机) 到仓库拉取镜像 https://hub.docker.com 运行镜像产生容器(实例,一个镜像可以运行多个) 镜像操作 搜索镜像 docker search imageName 拉取镜像 docker pull imageName:tag tag 版本号,如不指定默认是 latest 查看本地镜像 docker images 删除镜像 docker rmi imageID docker rmi [repositoryname]:[tag] 删除所有未加标签的镜像(untagged) docker rmi $(docker images | grep "^<none>" | awk "{print $3}") 重命名镜像 docker tag imageId imageName:tag 通过本地 Dockerfile 文件编译镜像文件 docker build -t mop:latest - < mopDockerfile 容器操作 进入容器 sudo docker exec -it ubuntu bash docker exec -it ardupilot bash 查看容器 docker ps -a -a:所有容器,包括停止的 -q:查看停止的容器,不加选项默认查看运行中的容器 保存容器 sudo docker save ubuntu > ubuntu_save.