RPC - A Four-Decade Journey Through Distributed Computing

The 40-Year Evolution of RPC: From Simple Procedure Calls to Modern Microservices The 40-Year Evolution of RPC: From Simple Procedure Calls to Modern Microservices Executive Summary Remote Procedure Call (RPC) has been a fundamental paradigm in distributed computing for over four decades. This article traces its evolution from simple client-server communications to modern microservices architecture, examining key developments, challenges, and the ongoing debate between developer convenience and system correctness. Through this historical lens, we’ll understand why RPC remains relevant in today’s cloud-native world. ...

2024-11-02 · 29 min · 6157 words

深入探讨字符串和 JSON 对比技术:多语言实现指南

深入探讨字符串和 JSON 对比技术:多语言实现指南 为什么字符串和 JSON 对比如此重要? 在讨论具体技术之前,我们先来看看为什么这个话题如此重要。在软件开发中,我们经常需要比较两个版本的文本或数据结构。这可能是为了: 版本控制:跟踪代码或配置文件的变化。 数据同步:确定需要更新的数据部分。 差异化展示:在用户界面上直观地显示变更。 调试和测试:快速识别系统行为的变化。 正确的对比技术可以极大地提高开发效率,减少错误,并为用户提供更好的体验。现在,让我们探讨各种实现方法。 字符串差异比较 Python 实现:使用 difflib Python 的 difflib 模块是一个强大而灵活的工具,适合各种文本比较任务。让我们看一个详细的例子: import difflib def string_diff(string1, string2): """ 比较两个字符串并以类似 git diff 的格式输出差异 """ diff = difflib.unified_diff( string1.splitlines(keepends=True), string2.splitlines(keepends=True), fromfile='原始文本', tofile='新文本', n=0 # 上下文行数,设为0只显示变化的行 ) for line in diff: if line.startswith('+'): print(f"\033[92m{line}\033[0m", end='') # 绿色显示新增行 elif line.startswith('-'): print(f"\033[91m{line}\033[0m", end='') # 红色显示删除行 elif line.startswith('^'): print(f"\033[94m{line}\033[0m", end='') # 蓝色显示变化位置 else: print(line, end='') # 示例使用 str1 = "Hello, World!\nThis is a test string.\nGoodbye!" str2 = "Hello, World!\nThis is a modified test string.\nSee you later!" print("原始文本:") print(str1) print("\n新文本:") print(str2) print("\n差异:") string_diff(str1, str2) 这个实现有几个值得注意的特点: ...

2024-10-01 · 4 min · 821 words

Nuxt 3 quickstart guide

Nuxt 3 quickstart guide Certainly! I’d be happy to translate this Nuxt 3 quickstart guide into English for you. Here’s the translated version: Nuxt 3 Beginner-Friendly Guide: Building Your First Application from Scratch Hey there! Welcome to the world of Nuxt 3! 👋 If you’re new to web development or just getting started with Nuxt, don’t worry. This guide will walk you through the basics of Nuxt 3 step by step. We’ll explain each concept using simple language and examples, making it easy for you to get started with this powerful Vue. js framework. Ready to begin your Nuxt 3 journey? Let’s dive in! ...

2024-10-01 · 21 min · 4287 words

Nuxt quickstart 新手友好版

nuxt.js quickstart 将这个nuxt.js quickstart ,请你扮演 nuxt 开发者,用更像是一个面向新手的博客的文风润色一下,如果有地方不详细,可以更详细的解释一下,请注意,要保留当前的目录结构,只需要润色 Nuxt 3 新手友好指南: 从零开始构建你的第一个应用 嗨,欢迎来到 Nuxt 3 的世界!👋 如果你是 Web 开发新手,或者刚刚接触 Nuxt,不用担心,这份指南会带你一步步了解 Nuxt 3 的基础知识。我们会用简单的语言和实例来解释每个概念,让你轻松入门这个强大的 Vue.js 框架。准备好开始你的 Nuxt 3 之旅了吗?让我们开始吧! 1. 创建你的第一个 Nuxt 3 应用 首先, 让我们从创建一个全新的 Nuxt 3 项目开始我们的冒险吧! 打开你最喜欢的终端, 跟着我一起敲几行命令: npx nuxi init my-awesome-nuxt-app cd my-awesome-nuxt-app npm install 哇! 就这么简单, 你已经创建了你的第一个 Nuxt 3 项目。但是等等, 这些命令到底做了什么? 让我来解释一下: npx nuxi init my-awesome-nuxt-app: 这行命令告诉 npx (一个 npm 包运行器) 使用 nuxi (Nuxt 3 的命令行工具) 来初始化一个新项目。my-awesome-nuxt-app 是你项目的名字, 当然, 你可以换成任何你喜欢的名字! ...

2024-10-01 · 7 min · 1485 words

如何对比字符串差异

https://www.perplexity.ai/search/wo-xiang-diff-xiang-ge-zi-fu-c-Erlew.brSYiuUnbWKP9uow 要在字符串之间进行差异比较,并以 git diff 的格式展示结果,可以使用 Python 的 difflib 模块。这个模块提供了方便的方法来比较两个字符串,并生成类似于 git diff 的输出格式。 使用 difflib 模块 以下是一个简单的示例,展示如何使用 difflib 来比较两个字符串并生成差异: import difflib def string_diff(string1, string2): # 使用 unified_diff 方法生成差异 diff = difflib.unified_diff( string1.splitlines(keepends=True), string2.splitlines(keepends=True), fromfile='string1', tofile='string2', ) # 打印差异 for line in diff: print(line, end='') # 示例字符串 str1 = "Hello, World!\nThis is a test string.\nGoodbye!" str2 = "Hello, World!\nThis is a modified test string.\nGoodbye!" # 调用函数 string_diff(str1, str2) 代码说明 导入模块: 首先导入 difflib 模块。 定义函数: 创建一个名为 string_diff 的函数,接受两个字符串作为参数。 生成差异: 使用 difflib.unified_diff() 方法生成差异,这个方法接受两个字符串列表(通过 splitlines() 方法分割),以及文件名参数。 打印结果: 遍历生成的差异并打印每一行。 输出示例 运行上述代码后,输出可能如下所示: ...

2024-09-25 · 3 min · 613 words

deploy hugo blog in vercel

我最近在创建一个 sora video 收集网站,使用 hugo 来开发,同时部署到 Vercel 上。在部署时遇到一些问题,以下是一个简单的记录。 Install Hugo 你可以查看 Hugo 官网来安装 hugo。在 mac 上,我使用 brew 安装。 brew install hugo Build in Local 我使用的是 https://gethinode.com/ ,A clean documentation and blog theme for your Hugo site based on Bootstrap 5. Create a new site hugo new site my-hinode-site && cd my-hinode-site Initialize the module system hugo mod init example.com/my-hinode-site echo "module.imports" >> hugo.toml echo "path = 'github.com/gethinode/hinode'" >> hugo.toml Start a development server ...

2024-02-21 · 1 min · 158 words

如何使用 Cloudflare worker 创建 gemini api 代理

https://zhile.io/2023/12/24/gemini-pro-proxy.html 如何使用 Cloudflare worker 创建 gemini api 代理 一、在 Cloudflare 中创建一个 worker gemini-api-proxy,保存并部署 export default { async fetch(request, env) { const url = new URL(request.url); url.host = 'generativelanguage.googleapis.com'; return fetch(new Request(url, request)) } } 二、添加自定义域名 可以直接使用 worker 触发器中的添加自定义域添加自定义域名。 不过这样不能确定使用的是哪个 ip,可能会存在请求时 gemini 提示地区不支持,这里可以自己设置 dns 解析 ip,通过这种方式来避免不支持的问题 以下内存转自 https://zhile.io/2023/12/24/gemini-pro-proxy.html 转到自己在 cf 上域名的控制面板,点击左侧菜单 DNS 来添加域名解析。 这里我使用自己的域名 gusibi.site,给它增加了子域名 A 记录:gemini-api.gusibi.site 这里有两个要点: 不要开启小黄云。 ip地址可以使用cf的优选工具选出来的高质量ip。 我这里用了两个我觉得还不错的ip,你们可以直接用,也可以自己去优选。 DNS解析记录操作完毕之后,点击左侧菜单Workers路由来让我们设置的域名和worker的路由关系。 在Workers路由界面,点击添加路由按钮,参考如下填写: 这里域名换成你刚才设置的那个,Worker也选择你之前创建的。点击保存即可。 完成这一步你就可以用你自己的域名来请求gemini了。 相关链接 : # 我们也要用Gemini Pro

2024-02-15 · 1 min · 69 words

coze_gpt4_api_get

https://www.dqzboy.com/16532.html https://github.com/deanxv/coze-discord-proxy 如何使用 打开 discord开发者平台 。 创建bot-A,并记录bot专属的token和id(COZE_BOT_ID),此bot为被coze托管的bot。 创建bot-B,并记录bot专属的token(BOT_TOKEN),此bot为我们与discord交互的bot。 两个bot开通对应权限(Administrator)并邀请进服务器,记录服务器ID(GUILD_ID) ( 过程不在此赘述)。 打开 coze官网 创建自己bot。 创建好后推送(Auto-Suggestion为default),配置discord-bot的token,即bot-A的token,点击完成后在discord的服务器中可看到bot-A在线并可以@使用。 配置环境变量,并启动本项目。 访问接口地址即可开始调试。 Render 可以直接部署 docker 镜像, 不需要 fork 仓库:Render docker run --name coze-discord-proxy -d --restart always \ -p 7077:7077 \ -v $(pwd)/data:/app/coze-discord-proxy/data \ -e USER_AUTHORIZATION="YOUR_VALUE_HERE" \ -e BOT_TOKEN="YOUR_VALUE_HERE" \ -e GUILD_ID="YOUR_VALUE_HERE" \ -e COZE_BOT_ID="YOUR_VALUE_HERE" \ -e PROXY_SECRET="YOUR_VALUE_HERE" \ -e CHANNEL_ID="YOUR_VALUE_HERE" \ -e TZ=Asia/Shanghai \ deanxv/coze-discord-proxy docker run --name coze-discord-proxy -d --restart always \ -p 7077:7077 \ -v $(pwd)/data:/app/coze-discord-proxy/data \ -e USER_AUTHORIZATION="YOUR_VALUE_HERE" \ -e BOT_TOKEN="YOUR_VALUE_HERE" \ -e GUILD_ID="YOUR_VALUE_HERE" \ -e COZE_BOT_ID="YOUR_VALUE_HERE" \ -e PROXY_SECRET="YOUR_VALUE_HERE" \ -e CHANNEL_ID="YOUR_VALUE_HERE" \ -e TZ=Asia/Shanghai \ deanxv/coze-discord-proxy 相关链接 :

2024-02-15 · 1 min · 98 words

RPC前世今生

Does developer convenience really trump correctness, scalability, performance, separation of concerns, extensibility, and accidental complexity?” Vinoski (2008) 开发者的便利性真的比正确性、可扩展性、性能、关注点分离、可扩展性和偶然复杂度更重要吗? 大纲 RPC 基础介绍 RPC 发展历程 RPC 介绍 远程过程调用(Remote Procedure Call,RPC)是一种允许两个实体通过通用请求/响应机制的通信通道进行通信的设计范例。RPC 的定义在过去三十年中发生了重大的变化和演变,因此 这里RPC 范式是一个广义的分类术语,指的是过去四十年中出现的所有 RPC 式系统。RPC 的定义经过几十年的发展。它已经从一个简单的客户端-服务器设计转移到一组相互连接的服务。虽然最初的 RPC 实现被设计为将计算外包给分布式系统中的服务器的工具,但 RPC 经过多年的发展,已经构建了一个与语言无关的应用程序生态系统。RPC 范式已经成为创建真正革命性的分布式系统的驱动力的一部分,并且在不同系统之间产生了各种通信方案和协议。 最简单的 RPC 实现如图1所示。在这种情况下,客户端(或调用方)和服务器(或被调用方)被一个物理网络分开。系统的主要组件是客户端例程/程序、客户端存根、服务器例程/程序、服务器存根和网络例程。存根是一个小程序,通常用作较大程序的替代程序(或接口)。客户端存根向客户端例程公开服务器例程提供的功能,而服务器存根向服务器例程提供类似于客户端的程序。客户端存根从客户端程序获取输入参数并返回结果,而服务器存根向服务器程序提供输入参数并获取结果。客户端程序只能与客户端存根交互,后者为客户端提供远程服务器的接口。这个存根还序列化客户端例程发送到存根的输入参数。类似地,服务器存根为服务器例程提供客户端接口,并处理发送到客户端的数据序列化。 当客户端例程执行远程过程时,它调用客户端存根,该存根序列化输入参数。这个序列化数据使用 OS 网络例程(TCP/IP)发送到服务器。然后,服务器存根将数据反序列化,并使用给定的参数提供给服务器例程。来自服务器例程的返回值再次序列化,并通过网络发送回客户端,在那里客户端存根对其进行反序列化,并显示给客户端例程。这个远程过程通常对客户端例程隐藏,并作为本地过程显示给客户端。RPC 服务还需要一个发现服务/主机解析机制来引导客户端和服务器之间的通信。 完整的 RPC 框架 在一个典型 RPC 的使用场景中,包含了服务发现、负载、容错、网络传输、序列化等组件,其中“RPC 协议”就指明了程序如何进行网络传输和序列化。 RPC 的发展历程 1969年11月,ARPAnet 开始建立。 1969年,美国国防部高级研究计划管理局(ARPA全称:Advanced Research Projects Agency)开始建立一个命名为ARPAnet的网络。最开始只有4个结点,分别是洛杉矶的加利福尼亚州大学洛杉矶分校、加州大学圣巴巴拉分校、斯坦福大学、犹他州大学四所大学的4台大型计算机。选择这四个节点的一个原因是要测试不同类型主机联网的兼容性。 1974年:Jon Postel 和 Jim White发表了RFC674 过程调用最早可以追溯到 Jon Postel 和 Jim White 在1974 年发表的 Procedure Call Protocol Documents Version 2(RFC674)。这个协议试图定义一种通用的方法,用于解决 NSW 项目中多个计算节点通信的问题。 ...

2023-05-11 · 5 min · 872 words

chassis.Run 运行了什么?

什么是 chassis? Chassis,是一种微服务模式。在这种模式中,用户并不需要自己去处理构建微服务过程中外部配置、日志、健康检查、分布式追踪等,而是将他们交给专门的框架来处理。用户可以更聚焦业务逻辑本身,简单、快速的开发微服务。 阅读此文,你可以得到什么? Chassis 运行时做了什么 chassis 运行时的隐藏操作。 chassis 设计思路的一些理解 Go-Chassis 是什么? Go-Chassis 是一个go语言的微服务开发框架,采用插件化设计,原生提供了可插拔的注册发现,加密解密,调用链追踪等组件。协议也是插件化的,支持http和grpc,也支持开发者定制私有协议, 开发者只需要专注于实现云原生应用即可。 云原生应用,基于云服务开发或者针对云服务开发部署的应用。 上图是go-chassis 的架构图,可以看出配置管理(Archaius)、服务注册(Registry)、Metrics、日志(Logger)都是独立的组件,分布式追踪、负载均衡、限流等都是以中间件(Handler Chain)的方式实现的。一个请求进来后会先通过server 转换成chassis invoker,然后经过Handler Chain,最后由Transport 转换成对应协议的response返回。 此篇文章主要关注go-chassis 启动过程时做了什么,以及做这些事情的用途。 一个例子 首先从 hello world 开始, 目录结构如下: . ├── conf # 配置目录,必须 │ ├── chassis.yaml # │ ├── microservice.yaml # 微服务相关配置,比如server name,注册中心地址 └── rest └── main.go chassis.yaml 内容为: --- cse: protocols: rest: listenAddress: "127.0.0.1:5001" transport: timeout: rest: 1 handler: chain: Provider: default: tracing-provider microservice.yaml 内容为: ...

2020-06-12 · 7 min · 1422 words