09 2022 档案
摘要:http网关 etcd3 API全面升级为gRPC后,同时要提供REST API服务,维护两个版本的服务显然不太合理,所以grpc-gateway诞生了。通过protobuf的自定义option实现了一个网关,服务端同时开启grpc和http服务,http服务接收到客户请求后转换为grpc请求数据,
阅读全文
摘要:interceptor拦截器 grpc服务端和客户端都提供了interceptor功能,功能类似middleware,很适合在这里处理验证、日志等流程。 在自定义Token认证的示例中,认证信息是由每个服务中的方法处理并认证的,如果有大量的接口方法,这种姿势就太不优雅了,每个接口实现都要先处理认证信
阅读全文
摘要:看一段代码 func main() { a := make([]int, 0, 5) fmt.Printf("%v:%p, len(a) = %d\n", a, &a, len(a)) a = append(a, 1) fmt.Printf("%v:%p, len(a) = %d\n", a, &a
阅读全文
摘要:负载均衡概述 早期的网站流量和业务功能都比较简单,单台服务器足以满足基本的需求,但是随着互联网的发展,业务流量越来越大并且业务逻辑也跟着越来越复杂,单台服务器的性能及单点故障问题就凸显出来了,因此需要多台服务器进行性能的水平扩展及避免单点故障出现。那么如何将不同用户的请求流量分发到不同的服务器上呢?
阅读全文
摘要:禁止直接通过ip方法80端口 server { listen 80 default; server_name _; error_page 403 /403.html; location = /403.html { root html; } location / { return 403; } } s
阅读全文
摘要:nginx的安全控制及SSL加密介绍 nginx的反向代理是如何来提升web服务器的安全呢? 答案是:安全隔离。 什么是安全隔离 通过代理分开了客户端到应用程序服务器端的连接,实现了安全措施。在反向代理之前设置防火墙,仅留一个入口供代理服务器访问。 如何使用SSL对流量进行加密 翻译成大家能熟悉的说
阅读全文
摘要:认证 grpc默认内置了两种认证方式 SSL/TLS认证方式 基于Token的认证方式 同时,gRPC提供了接口用于扩展自定义认证方式 TLS认证示例-客户端、服务端双向认证 详细实现文档 Token认证示例 再进一步,继续扩展hello-tls项目,实现TLS + Token认证机制 目录结构:
阅读全文
摘要:gRPC的基本使用非常简单,看完这部分的第一个示例就可以直接用了。但是在实际环境中,我们不会仅仅满足于能用,而是要更好的使用。一个完整的服务包括:授权认证、数据追踪、负载均衡...,我们从一个简单的项目开始,说明gRPC的基本使用姿势,然后一点点细化扩展,逐步深入完善,打造一个完整的RPC服务。 H
阅读全文
摘要:目录 安装 第一步安装protoc编译器: linux下载地址 windows64下载地址 安装protoc-gen-go和protoc-gen-go-grpc两个插件 go get google.golang.org/protobuf go get google.golang.org/grpc g
阅读全文
摘要:grpc是一个高性能、通用的开源rpc框架,其由google主要面向移动应用开发并基于http/2标准协议而设计,基于Protobuf(protocol buffers)序列化协议开发,且支持众多开发语言。 gRPC提供了一种简单的方法来精确地定义服务和为iOS、Android和后台支持服务自动生成
阅读全文
摘要:go官方rpc库:net/rpc 包rpc提供了通过网络访问一个对象的输出方法的能力。 服务器需要注册对象, 通过对象的类型名暴露这个服务。注册后这个对象的输出方法就可以远程调用,这个库封装了底层传输的细节,包括序列化(默认GOB序列化器)。 服务器可以注册多个不同类型的对象,但是注册相同类型的多个
阅读全文
摘要:go rpc开发指南 本书首先介绍了使用Go官方库开发RPC服务的方法,然后介绍流行gRPC库以及其它一些RPC框架如Thrift等,后面重点介绍高性能的分布式全功能的RPC框架 rpcx。读者通过阅读本书,可以快速学习和了解Go生态圈的RPC开发技术,并且应用到产品的开发中。 rpc介绍 远程过程
阅读全文
摘要:Any Any 消息类型可以让你使用消息作为嵌入类型而不必持有他们的.proto定义. Any把任意序列化后的消息作为bytes包含, 带有一个URL, 工作起来类似一个全局唯一的标识符. 为了使用Any类型, 需要导入google/protobuf/any.proto. 参考文档 Oneof 如果
阅读全文
摘要:下载依赖 go get -u google.golang.org/protobuf 目录结构 编写hello.proto文件 syntax = "proto3"; package proto; option go_package = "my_proto/proto"; import "google/
阅读全文
摘要:语言指南 这份指南描述如何使用protocol buffer语言来构建你的protocol buffer数据,包括.proto文件语法和如何从.proto文件生成数据访问类. 覆盖protocol buffers语言的proto3版本 拆分之后的章节列表: 定义消息类型 Scalar值类型 默认值
阅读全文
摘要:实际案例 目录结构图 proto/base/base.proto文件 syntax = "proto3"; package base; option go_package = "my_protobuf/proto/base"; message Result { string name = 1; in
阅读全文
摘要:Protobuf的定义 protobuf是一种用于序列化结构数据的工具,实现数据的存储与交换,与平台和语言无关。 序列化: 将结构数据或对象转换成能够用于存储和传输的格式。 反序列化: 在其它计算机环境中,将序列化后的数据还原为结构数据或对象 定义的数据结构,然后使用protoc编译生成源代码,在各
阅读全文
摘要:前言 在 连载九 讲解构建Scratch镜像时,我们编译可执行文件用了另外一个形式的命令,不知道你有没有疑问? $ CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o gin_blog . 说明 我们将讲解命令各个参数的作用,希望你在
阅读全文
摘要:前言 本章节将实现如下功能: 生成二维码 合并海报(背景图+二维码) 实现 首先,你需要在 App 配置项中增加二维码及其海报的存储路径,我们约定配置项名称为 QrCodeSavePath,值为 qrcode/ 生成二维码 安装:go get -u github.com/boombuler/barc
阅读全文
摘要:前言 在本节,我们将实现对标签信息的导出、导入功能,这是很标配功能了,希望你掌握基础的使用方式 另外在本文我们使用了 2 个 Excel 的包,excelize 最初的 XML 格式文件的一些结构,是通过 tealeg/xlsx 格式文件结构演化而来的,因此特意在此都展示了,你可以根据自己的场景和喜
阅读全文
摘要:优化你的应用结构和实现redis缓存 规划 在本章节,将介绍以下功能的整理: 抽离、分层业务逻辑:减轻 routers/*.go 内的 api方法的逻辑(但本文暂不分层 repository,这块逻辑还不重) 增加容错性:对 gorm 的错误进行判断 Redis缓存:对获取数据类的接口增加缓存设置
阅读全文
摘要:优化配置结构及实现图片上传 一天,产品经理突然跟你说文章列表,没有封面图,不够美观,!)&¥!&)#&¥!加一个吧,几分钟的事 你打开你的程序,分析了一波写了个清单: 优化配置结构(因为配置项越来越多) 抽离 原 logging 的 File 便于公用(logging、upload 各保有一份并不合
阅读全文
摘要:Cron定时任务 在实际的应用项目中,定时任务的使用是很常见的。你是否有过 Golang 如何做定时任务的疑问,莫非是轮询? 在本文中我们将结合我们的项目讲述 Cron 介绍 我们将使用 cron 这个包,它实现了 cron 规范解析器和任务运行器,简单来讲就是包含了定时任务所需的功能 Cron表达
阅读全文
摘要:docker介绍 在这里简单介绍下Docker,建议深入学习 Docker 是一个开源的轻量级容器技术,让开发者可以打包他们的应用以及应用运行的上下文环境到一个可移植的镜像中,然后发布到任何支持Docker的系统上运行。 通过容器技术,在几乎没有性能开销的情况下,Docker 为应用提供了一个隔离运
阅读全文
摘要:http.Server-Shutdown() package main import ( "context" "fmt" _ "gin_log/models" "gin_log/pkg/setting" "gin_log/routers" "log" "net/http" "os" "os/sign
阅读全文
摘要:编写一个简单的文件日志 在上一节中,我们解决了API’s可以任意访问的问题,那么我们现在还有一个问题。 就是我们的日志,都是输出到控制台上的,这显然对于一个项目来说是不合理的,因此我们这一节简单封装log库,使其支持简单的文件日志! 新建logging包 我们在pkg下新建logging目录,新建f
阅读全文
摘要:使用JWT进行身份验证 在前面几节中,我们已经基本的完成了API’s的编写 但是,还存在一些非常严重的问题,例如,我们现在的API是可以随意调用的,这显然还不够完美,是有问题的 那么我们采用 jwt-go (GoDoc)的方式来简单解决这个问题 下载依赖包 首先,我们下载jwt-go的依赖包 go
阅读全文
摘要:编写article的apis和models 定义接口 本节编写文章的逻辑,我们定义一下接口吧! 获取文章列表:GET("/articles") 获取指定文章:POST("/article/:id") 新建文章:POST("/article") 更新指定文章:PUT("/article/:id") 删
阅读全文
摘要:定义接口 本节正是编写标签的逻辑,我们想一想,一般接口为增删改查是基础的,那么我们定义一下接口吧! 获取标签列表:GET(“/tags”) 新建标签:POST(“/tags”) 更新指定标签:PUT(“/tags/:id”) 删除指定标签:DELETE(“/tags/:id”) 编写路由空壳 开始编
阅读全文
摘要:下载beego/validation go get github.com/astaxie/beego/validation 直接用途 package main import ( "fmt" "github.com/astaxie/beego/validation" ) type User struc
阅读全文
摘要:gorm默认支持软删除 如果想要支持联合唯一索引,就需要用到一个gorm的插件库:gorm.io/plugin/soft_delete By default, gorm.Model uses *time.Time as the value for the DeletedAt field, and i
阅读全文
摘要:初始化项目目录 conf:用于存储配置文件 middleware:应用中间件 models:应用数据库模型 pkg:第三方包 routers 路由逻辑处理 runtime 应用运行时数据 初始化项目数据库 新建blog数据库,编码为utf8_general_ci 在blog数据库下,新建以下表 标签
阅读全文
摘要:思考 首先,在一个初始项目开始前,大家都要思考一下 各种程序配置,写在代码中好吗? API的错误码硬编在程序中,合适吗? DB句柄谁都去open,好吗? 获取分页等公共参数,不统一管理起来,好吗? 显然在较正规的项目中,这些问题的答案都是不可以 [https://github.com/go-ini/
阅读全文
摘要:Nginx 如何变成一个代理服务器?Nginx 又如何将客户端的请求转发给其他的服务器?本内容将学习 Nginx 的反向代理知识。 反向代理概述 正向代理代理的对象是客户端,反向代理代理的对象是服务端,这是两者之间最大的区别。 nginx既可以实现正向代理,也可以实现反向代理。 我们先来通过一个小案
阅读全文
摘要:rewrite之rewrite指令 该指令通过正则表达式的使用来改变 URI。可以同时存在一个或者多个指令,按照顺序依次对 URL 进行匹配和处理。 URL 和 URI 的区别: URI:统一资源标识符 URL:统一资源定位符 | 语法 | 默认值 | 位置 | | | | | | rewrite
阅读全文
摘要:nginx跨域问题的原因分析 跨域问题,我们主要从以下方面进行解决: 什么情况下会出现跨域问题 实例演示跨域问题 具体的解决方案是什么 同源策略 浏览器的同源策略:是一种约定,是浏览器最核心也是最基本的安全功能,如果浏览器少了同源策略,则浏览器的正常功能可能都会受到影响。 同源:协议、域名(ip)、
阅读全文
摘要:gin启动服务的三种方式 func main() { engine := gin.Default() engine.GET("/", func(context *gin.Context) { context.JSON(200, gin.H{"msg": "OK2"}) }) // 启动http服务的
阅读全文
摘要:// 方法1:使用go中标准库里的json编码成[]byte,然后再解码到map里 //data, _ := json.Marshal(&User) //m := make(map[string]any) //json.Unmarshal(data, &m) // Struct2map 方法2:通过
阅读全文
摘要:go语言数组 数组是一个由固定长度的特定类型元素组成的序列,一个数组可以由零个或多个元素组成。因为数组的长度是固定的,所以在go语言中很少直接使用数组。 在数组的定义中,如果在数组长度的位置出现“…”省略号,则表示数组的长度是根据初始化值的个数来计算: func main() { a := [...
阅读全文