首页 文章 精选 留言 我的

精选列表

搜索[数据库迁移],共10000篇文章
优秀的个人博客,低调大师

企业项目迁移go-zero全攻略(一)

作者:Mikael 最近发现 golang 社区里出了一个新兴的微服务框架。看了一下官方提供的工具真的很好用,只需要定义好 .api 文件模版代码都可以一键生成,只需要关心业务;同时 core 中的工具极大减少了开发成本。 废话不多说,来看看这个微服务框架:go-zero 起源 聊聊与go-zero结缘 最先接触go-zero是2020年10月国庆假期,说来也巧,看到有人在go-micro群中问go-zero情况,当时go-zero作者在群中就大概回答了一下,引起了我的好奇,当时公司用的go-micro1.x,因为go-micro版本真的太混乱了,2还没多少人用明白,现在又搞了个3,而且这几个大版本之间高度不兼容,简直一团糟。我抱着好奇心去github.com查看了go-zero,当时并没有因为它的star数、文档少而放弃,哈哈,抱着试玩的心态去go get它,从此发现了新大陆,并加入了go-zero群,开始了go-zero之旅。 选择它的几点原因 微服务:在现在这个大环境下,单体服务诟病已经越来越多了,项目大起来之后 “牵一发而动全身” 的教训比比皆是,维护越来越困难,测试测起来也是很头疼,构建速度慢等等,在这样趋势下拥抱微服务成为了大趋势,go-zero就是一个微服务框架并且能为我解决很多实际项目中遇到的痛点、难点 稳定性:内外同源。稳定性是我很看重的,他们公司内外同源势必保证了此框架的稳定性。 高并发:经历了2020年疫情期间,“晓黑板” 轻松获得支撑千万日活服务 工作效率:说到工作效率,必须要提的就是goctl,goctl配合go-zero所有代码基本都是可以通过这个工具生成,只需要关心自己的业务逻辑即可,包括一键生成dockerfile,k8s的yaml文件,简直不要太爽,大大提高了工作效率 代码质量:大概看了一些go-zero的源码,代码质量上感觉还是没得喷的,至少感觉比我自己写的好很多,哈哈,这个每个人看法不同,大家可以去亲自看一下。 团队:当时加了go-zero作者微信,感觉他为人很谦和,无论问一些比较基础的东西还是一些线上实战经验,也总是会耐心给我解答、意见,在使用期间我也提了一些bug,go-zero团队都能及时的解决,迭代速度真的让我惊艳。大家应该都知道,在国内做开源有多么不容易。 对比go其他微服务框架:go的微服务框架大概我玩过go-micro、go-kit、kratos、rpcx、go-zero。 go-micro我开始就说了是版本真心有点混乱 go-kit也不错但是资料相对来说较少 kratos经过b站源码泄漏大家应该都知道它了,前一段时间都断更了,差点安乐死,毛神在issue中说太忙了,不过他们在出2.0版本了,还是很期待 rpcx 玩了一下玩的不多,但是他们宣传是“好未来”也在用,go-zero就是“好未来”的呀,哈哈 go-zero 上面我都说过了,就不再提了。 设计架构 在介绍go-zero实际使用前,先说一下整体架构,更方便理解 CI/CD Step1:本地deveploer开发好代码之后提交到gitlab(这里分支就不详细说明了) Step2:jenkins,使用pipline方式部署 从gitlab拉取代码 docker build ,基于最新gitlab上的code构建镜像 docker push,将构建好的镜像推送到镜像仓库(当然一般都是有自己私有镜像仓库比如harbor,用阿里云的也可以) kubectl apply -f xxx.yaml :使用kubectl 部署到k8s中 (阿里云k8s容器服务那么好用,不用岂不可惜?) kubectl部署之后,k8s就会根据你的service中的yaml定义的镜像来你的镜像仓库拉取刚才你打包的最新镜像,so~~上线成功啦! 嗯,有的同学说,阿里云k8s好用是好用,可是我不会写or不想写Dockerfile,不会写k8s的yaml or 不想写,没关系,goctl说放开它,让我来 生成 Dockerfile $ goctl docker -go user.go 生成k8s yaml $ goctl kube deploy -name user-api -namespace blog -image user:v1 -o user.yaml -port 2233 所以,就是这么简单 访问流程 app/web/pc 透过防火墙,首先访问到阿里云的负载均衡SLB,同时SLB可以将你的后端服务器ip隐藏起来,同时可以预防DDOS攻击,虽然有额度的,但是好过没有~~,然后SLB访问到前面的nginx,nginx作为代理使用,k8s中的service通过 nodeport方式暴露出来在nignx中代理到该service,同时在nginx中上报日志到kafka,然后api可以在etcd中拿到多个rpc节点,调用多个后端rpc服务,rpc负责跟db交互、或者调用其他rpc获取数据(当然api、rpc之间是通过etcd动态发现的)返回给api,api就是聚合数据,然后层层返回到客户端。 整体架构都是高可用高可用 项目设计 项目地址:https://github.com/Mikaelemmmm/gozerobasic go的项目比较灵活不像java已经形成统一标准化了,所以对于不同项目的结构都不一样,我的做法是如下: 整个项目使用的一个大仓,项目fishtwo根目录下: app : 应用内部程序 build:构建、以及脚本等 lib:应用程序用到的内部库 app下分为3个模块: gateway:api服务 services: rpc服务 jobs:日常要处理的任务(这个可以使用 go-zero 作者的 go-queue ,测试了下很好用,哈哈,后面搞好也会写进来) 下一篇我们来看看: 怎么改造 gateway 服务? 怎么改造 rpc 服务? jobs 怎么定义?怎么和项目结合? > 未完待续~~~ 框架地址 https://github.com/tal-tech/go-zero 欢迎使用 go-zero 并 star 支持我们 👍

优秀的个人博客,低调大师

从 React 迁移到 TypeScript:忍受了 15 年的 JavaScript 错误从此走远

云栖号资讯:【点击查看更多行业资讯】在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! Beta 版的 Execute Program 是用 Ruby 和 JavaScript 编写的。之后,我们分几步将整个应用完全移植到了 TypeScript 上。本文介绍的是移植的第一步,也就是前端的部分。 在 Execute Program 的原始 JavaScript 前端中,我经常会犯一些小错误。例如,我会将错误的 prop 名称传递给 React 组件,或者遗漏某个 prop,抑或传递错误的数据类型。(Prop 是作为参数发送到 React 组件的数据。组件将一些 props 传递给自己的某个子组件,以此类推,这是很常见的。) 对于像 JavaScript 和 Ruby 这样的动态语言来说,这不是个小问题。过去 15 年来我一直在学习该如何应对这种错误问题。我在之前谈论的是 2011 年代的情况,其中讨论的缓解措施确实有些用途,但它们无法随着系统的发展顺利地扩展下去,而且我们忘掉它们时也没有安全网可用。 我觉得 15 年时间已经够长了。我想回到静态类型系统的怀抱,毕竟这种系统中根本不会出现这类错误。彼时我们有几个选项:Elm、Reason、Flow、TypeScript 和 PureScript。(这里举了一部分例子。)最后我决定使用 TypeScript 是因为: TypeScript 是 JavaScript 的超集,因此移植起来很容易。移植回来也更容易些:只需删除类型定义即可,然后我们又回到了 JavaScript。 TypeScript 编译器使用 TypeScript 编写,并作为已编译的 JavaScript 代码分发,因此我们可以在自己的 Web 应用中运行它。我们的 TypeScript 课程正是这样做的:在浏览器中评估用户的 TypeScript 代码,以避免网络延迟。 这一条是我们的业务特有的:TypeScript 比其他选项更受欢迎。这意味着更多的人希望从像我们这样的课程中学习 TypeScript。用 TypeScript 编写 Execute Program,让我们可以制作出更好的 TypeScript 课程。 在 2018 年 10 月,我们用了大约两天时间将前端 JavaScript 代码移植到了 TypeScript。下面的图表显示了在移植前和移植后每种语言拥有的代码量。 当时我们还是 pre-beta 版本,所以系统还很小,只有大约 6,000 行。这张图上没有涉及移植后的情况;我们将在以后的文章中具体介绍相关内容。 在这次移植之后,React prop 问题消失了。下面我们会看几个示例,首先是一个简单的例子。以下是渲染“Continue”按钮的代码,这个按钮出现在我们课程的每个文本段落之后: <Button autofocus={true} icon="arrowRight" onClick={continue} primary > Continue </Button> 这个 Button 组件的 props 的类型如下所示。当读取诸如 autofocus?: boolean 之类的属性类型时:“autofocus”是属性的名称;“?”表示它是可选的;“:”将属性名称与其类型分开;而“boolean”是类型。最后一个属性类型 onClick 表示“一个不带参数且不返回任何内容的函数”。如果你不熟悉 TypeScript 的函数类型语法,可以在我们的课程中全面了解 TypeScript 的函数类型。 type ButtonProps = { autofocus?: boolean icon?: IconName primary?: boolean onClick: () => void } 如果将“autofocus”prop 从 true 更改为 1,会发生什么?现在,我们在类型系统期望一个布尔值的地方传递了一个数字值。不到一秒钟后,编译器将在下面显示错误。(这里删除了一些不相关的细节;本系列文章中所有涉及到错误的地方都会这样处理。) src/client/components/explanation.tsx(13,27): error: Type 'number' is not assignable to type 'boolean | undefined'. 有害代码在 vim 中也变成了红色。修好它后,红色消失了。解决错误只需要几秒钟。在 Ruby 或 JavaScript 中,我可能会花几分钟的时间手动测试应用程序,并反复浏览它的状态才能知道到底发生了什么事情。我也可以依靠自动化测试,但是我们在另一篇文章中介绍了测试 vs 类型的问题。 这个整数到布尔的更改是对类型系统的一次简单而低风险的测试。Button 的 icon 属性显示了更高级的用法。下面还是 Button 调用: <Button autofocus={true} icon="arrowRight" onClick={continue} primary > Continue </Button> 看起来 icon prop 只是一个字符串:“arrowRight”。在运行时,在已编译的 JavaScript 代码中,它将是一个字符串。但是在上面显示的 ButtonProps 类型中,我们将其定义为 IconName,后者是在其他地方定义的。在查看其定义之前,让我们先看看这个类型的作用。假设我们将“icon”prop 更改为“banana”。我们实际上没有名为“banana”的图标。 <Button autofocus={true} icon="banana" onClick={continue} primary > Continue </Button> 不到一秒钟后,TypeScript 编译器拒绝了这一更改: src/client/components/explanation.tsx(13,44): error: Type '"banana"' is not assignable to type '"menu" | "arrowDown" | "arrowLeft" | ... 21 more ... | undefined'. 编译器说“icon”不能是任意字符串。它必须是我们定义为 icon 名称的 24 个字符串之一。编译器将拒绝任何使我们引用不存在图标的更改;这不是有效的程序,甚至无法开始执行。 有多种方法可以实现 IconName 类型。一种是编写一种类型,该类型显式列出所有可能的 icon 名称。然后,我们必须使 icon 名称与其在磁盘上的图像文件保持同步。这种类型可能是这样的: type IconName = "menu" | "arrowDown" | "arrowLeft" | "arrowRight" | ... 翻译成中文:“这里会静态地保证 IconName 类型的一个值是此处指定的字符串之一,但不能是其他任何字符串。”(这个类型是我们两堂课程涵盖的两个主题的组合:字面量类型和类型联合) 我们的 IconName 未被定义为字面量类型的简单联合。让图标名称列表与文件列表保持同步是很无聊的工作,我们可以让计算机来完成它!相反,我们的 icon.tsx 文件如下所示: export const icons = { arrowDown: { label: "Down Arrow", data() { return <path ... /> } }, arrowLeft: { label: "Left Arrow", data() { return <path ... /> } }, ... } 实际的 SVG < path/> 标签就在源代码中,在以 icon 名称为键的对象中。(也可以在不将 SVG 内联到源文件中的情况下执行此操作。例如,我们可以使用一些 Webpack 技巧将图像保存在它们自己的文件中,但仍然可以确保列表中的每个图标也都存在于磁盘上。到目前为止,这种简单的解决方案对我们来说是很好用的。) 通过这种方式定义 icon 后,我们可以使用一行代码自动提取其名称的联合类型(union type): export type IconName = keyof typeof icons (这里的意思是,你可以认为该类型表示“每当某物的类型为”IconName”时,它必须是与 icons 对象的键之一匹配的字符串。) 这样就搞定了;并不需要其他类型层面的工作。剩下的代码只是一个简单的 Icon React 组件,它在列表中查找图标并返回其 SVG 路径。这个函数中没有明确的 TypeScript 类型。它看起来像是纯粹的 JavaScript 代码,但它也经过了类型检查。这是一个最小版本,其中删除了所有无关的细节: export function Icon(props: { name: IconName }) { return <svg> {icons[props.name].data()} </svg> } 现在,我们可以将 SVG 标签放入这个源文件中,并将新 icon 拖放到“icons”列表中。当我们这样做时,这个 icon 就可以在 Button 组件,以及系统内接受 icon 名称的其他任何部分中使用。如果我们从列表中删除一个 icon,则系统中引用该 icon 的所有部分都将立即无法编译,从而确保没有过时的 icon 引用在运行时导致错误。 这些示例按照静态类型标准来说是很简单的,但我认为它们证明了 Web 应用程序中有多少可以轻松实现的改进之处。一个应用程序中的大多数代码都不涉及高级类型系统功能;多数需求仅仅是“确保我们传递正确的 props”和“确保我们的图标确实存在”之类的简单事情。 我们在整个系统中都做了这种事情。其他的一些示例: 我们在整个系统中使用了一个 Note 组件。它具有一个 tone prop 来确定提示的样式:“info”“warning”“error”等。如果我们不再使用其中某个 tone 选项,则我们将从联合类型中将其删除,并且所有引用这个 tone 的 Note 将出错,直到我们更新它们。 我们链接到的每个 URL 都将静态保证存在。当我们重命名或删除 URL 时,链接到它的每个组件都无法编译,直到我们对其进行更新以匹配为止。 当我们链接到这些 URL 时,类型系统可确保我们填充 URL 中的所有空缺。例如,路径“/courses/:courseId/lessons/:lessonId”具有两个 hole,“courseId”和“lessonId”。如果我们尝试链接到该路径,但忘记提供“courseId”,则代码将无法编译。 我们在客户端上发出的每个 API 请求都会被静态确保与相应服务端 API 端点的负载结构匹配。如果我们在端点中重命名一个属性,哪怕属性在嵌套的 API 对象的内部深处,引用该端点属性的任何代码也都将无法编译,直到我们对其更新以匹配为止。我们在另一篇文章中介绍了细节。 诸如此类的问题经常会出现在编程工作中,尤其是在动态语言中非常常见;但我们无需编写任何自动测试,也用不着什么手动测试,就可以从静态上避免这些问题。有些问题解决起来需要费些功夫。我们的 API 路由器验证写起来很麻烦。但是写多了就顺手了。上面的单行“IconName”类型实际上是问题的完整解决方案。如果将其复制到 TypeScript 文件中,它就能起作用。 将我们的前端代码移植到 TypeScript 仅仅是个开始。那之后,我们又将后端从 Ruby 移植到了 TypeScript,然后在移植后的 9 个月内对其进行了扩展和维护。 【云栖号在线课堂】每天都有产品技术专家分享!课程地址:https://yqh.aliyun.com/live 立即加入社群,与专家面对面,及时了解课程最新动态!【云栖号在线课堂 社群】https://c.tb.cn/F3.Z8gvnK 原文发布时间:2020-06-01本文作者:Gary Bernhardt本文来自:“infoq”,了解相关信息可以关注“infoq”

优秀的个人博客,低调大师

迁移潮来袭!数十个项目宣布即将停止支持 Python 2

之前我们曾报道过Python 2.7 将于 2020 年退休的消息,随着该时间节点的临近,已陆续有一大批 Python 项目宣布将在 2020 年之前放弃对 Python 2.7 的支持,包括pandas、Zulip、IPython、NumPy等等。 事实上,几乎目前所有主要的开源 Python 包现在都同时支持 Python 3.x 和 Python 2.7 ,并且多数已支持这两种语言版本多年。虽然市面上有能够有效保持兼容性的工具和技术,但在许多代码的开发过程中,仍然会有小的摩擦,开发者也不打算无限期地保持这种兼容性。眼看着官方即将停止支持 Python 2 ,以及越来越多的人使用、教学和推荐 Python 3 ,这些 Python 包的作者自然也更倾向于放弃 Python 2 ,从而简化代码并更好地利用 Python 3.x 的许多新功能。 列表如下: 详细时间表: 列表地址:https://python3statement.org/

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册