#587 Lua (3): 面向对象

2021-07-03

由于想了解一下 OpenResty, 先看看 Lua 的语法。
这是第三篇,关于 Lua 面向对象的一些简单例子。

#586 Lua (2): 其他姿势

2021-07-03

由于想了解一下 OpenResty, 先看看 Lua 的语法。
这是第二篇,接着说 Lua 基础语法。

#585 吊炸天的 GitHub Copilot

2021-07-02

一个月前看到了微软通过 OpenAI 独家授权的 GPT-3 弄了一个低代码编程语言 Power Fx,可以直接通过简单的自然语言来完成数据的各种复杂操作。
我看到演示,当时就非常惊讶。不过当时我觉得,估计也就只能到这个地步了(弄弄 Excel 公式),想要真的生成可用代码,可能还得等几年。
今天有看到了 GitHub 搞的这个 Copilot,我是真的惊了。
看网上的演示,就根据一点点注释,可以生成各种语言的代码,还可以提供多种选择。
Your AI pair programmer,真是此言不虚!
除非是从 GitHub 已有仓库中拿出来的,然后人工标注其用途(可能性非常小),否则这真是逆天了,超出了我对现阶段人工智能水平的认知。
不过现在是技术预览阶段,我已提交申请,不过不知道什么时候可以通过,我是真的想试试,要是用上这等神器,必定可以省不少事。
话说回来,老码农的价值肯定是会被压缩了一些些。
首先,还是得看看 Copilot 的水平,再说。
我现在真是太激动了,虽然可能会让程序员变得更卷,但是看到这样的技术进步,我还是非常开心。

Update @ 2021-11-01

Copilot 已经支持 neovim 和 JetBrains IDE (IDEA, PyCharm, WebStorm, PphStorm, Goland...) 了。

Update @2022-06-23

GitHub Copilot 宣布免费到 08/22,今后要收费,每个月 8 美元。我已经非常习惯 Copilot 了,但是这个价格对我来说还是不可接受的。

我搜索了一下 VSCode 的拓展商店,看到有一个新的 GitHub Copilot Nightly 版本,估计是给免费用户使用的。
另外还发现一个 GitHub Copilot Labs 拓展,可能是更加完善的版本,应该也是收费。

Update @2022-06-27

#583 Lua (1): 基础语法

2021-07-02

由于想了解一下 OpenResty, 先看看 Lua 的语法。

Lua 是啥

  • 开源
  • 嵌入式
  • 脚本语言引擎 (由标准 C 编写,非常容易和 C/C++ 相互调用)
  • 语法简单
  • 没有强大的标准库

我的理解是,给 C 项目嵌入 lua 语言支持,然后通过 lua 来实现上层业务逻辑的快速开发,或者系统的灵活拓展。

除了官方 Lua 之外,还有这两个实现:

  • LuaJIT OpenResty 当前采用的就是这个玩意(之前是标准 Lua) 重点!
  • Lupa Python 模块,实现了对 Lua 脚本的解析

安装

sudo apt install -y lua5.4

命令行输入 lua 可以启动一个交互 SHELL。

语法

  1. 不像 Python 用缩进区分代码段,也不像 C 用花括号,而是用 end;
  2. 约定:下划线打头的大写字母组成的标识符作为 Lua 内部全局变量

关键字

and or
do while for repeat until break
if then else elseif end
true false nil
function return
in
local
goto

数据类型

  • nil
  • boolean
  • number:1,1.1,1e2
  • string 单引号,双引号,或 [[ + ]]
  • table 数组(和 PHP 类似)
  • userdata C 语言结构
  • function 函数被视为一种数据结构
  • thread
-- type 返回字符串
type(a) -- nil

字符串

  • 字符串连接:..
  • 计算长度:一元操作符 #,也用于计算数组长度
常见操作
  • string.upper, string.lower, string.reverse, string.len
  • string.format
  • 模式匹配:
  • string.match
  • string.gmatch
  • string.sub
  • string.gsub(mainString, findString, replaceString, num)
  • string.find(str, substr, )
  • string.rep(str, n) 重复
  • string.char(arg), string.byte(arg[,int]) 整形和字符的转换

数组

  • 除了 nil 之外的所有值都可以用作索引
  • 方括号,和小数点取值都支持
    小数点取值的话,要求必须是合法标识符
常见操作
  • table.concat(table[, sep[, start[, end]]]) join
  • table.insert(table[, pos], value)
  • table.remove(table[, pos])
  • table.sort(table[, comp])

类型转换

数字 字符串

变量

  1. 默认为全局变量(和 Python 类似)
  2. 本地变量需要用 local 声明
  3. 没有初始化的变量为 nil
  4. 删除变量:x = nil,删除数组中的元素也是赋值 nil

函数

function average(...)
   result = 0
   local arg = {...}
   for i, v in ipairs(arg) do
      result = result + v
   end
   print("总共传入 " .. select("#",...) .. " 个数")
   return result / select("#", ...)
end
  1. 三个点 ... 表示可变参数,固定参数需要放到可变参数前面
  2. select('#', ...) 可变参数长度
  3. select(n, ...) 可变参数切片

异常处理

assert

error(message[, level]) -- 相当于抛出异常
-- level 0, 1, 2 分别表示没有附加信息,错误位置(文件 + 行号),调用函数

pcall(func, ...) -- 调用函数,返回是否有错误(boolean),错误信息
xpcall(func, error_callback, ...) -- 增加了异常处理

debug 模块

这里面有好多内容。

debug.debug -- 进入交互模式
debug.trackback -- 调用栈

其他

  1. lua 会先计算左值,再赋值,所以支持和 Python 一样的 a, b = b, a 这种变量交换。
  2. 注释:
  3. 单行 --
  4. 多行 --[[ ]]
  5. 逻辑运算中不等于:~=,不是常见的 !=,需要注意
  6. 自动垃圾回收,手动的话调用 collectgarbage

#582 Go 微服务生态

2021-06-30

micro

曾经最优秀的,最有前途的 Go 微服务框架。

但是后来发生了一些事...

框架的所有者是 Micro 公司,在 v3 的时候(2020 年下半年),他们决定更改项目定位。

公司运营一个云平台,叫做 m3o,专门提供 micro 项目托管,概念叫做 Micro as a Service。

新版本 micro/micro shields.io 目标由微服务框架改成云原生平台,并且协议由 Apache License 2.0 变更成了 Polyform Shield License(我查了一下,这个协议大意是说如果使用者和所有者发生竞争,则授权取消)。

原项目 microhq/go-micro 进行归档,不再维护。
后来项目转给了他们公司 CTO 账户下 asim/go-micro shields.io,继续维护。
再后来项目更名为 nitro (asim/nitro, gonitro/nitro),还搞了官网啥的。
再后来又放弃了,退回 asim/go-micro。
乱!

云原生就云原生,原有项目没有精力维护也没什么关系,做出这些决定一会儿一变,真是作得一批。
新协议更加是令人无语,杜绝竞争这一条就是堵住了所有商业使用的可能性(据说 nitro 时期也曾一度变更为 Polyform 协议)。

总之,我觉得这个框架要被玩死。

如果像我一样刚接触 Go 微服务,我觉得可以跳过 micro,或者仅用于学习参考。

gokit

A standard library for microservices.
https://github.com/go-kit/kit shields.io

它的定位和 micro 不一样,micro 是一个大而全的微服务框架,而 gokit 是一些在微服务中有用的工具,用于开发自己的框架。

国产项目

kratos

go-kratos 是一个基于 Go 语言的轻量级微服务开发框架,由 Bilibili 交给开源社区维护,采用 MIT 开源协议。项目致力于提供云原生应用开发所需的基础能力,帮助开发团队快速构建结构清晰、易于测试和维护的后端服务。

核心功能包括:HTTP/gRPC 双协议支持,通过 Protocol Buffers(Protobuf)定义 API 并生成代码;提供中间件机制,支持日志、认证、参数校验、链路追踪和指标监控;支持可插拔的配置管理、服务注册与发现,以及统一的错误处理机制。框架不强制绑定数据库、ORM 或特定基础设施,便于按需集成现有技术栈。

go-kratos 适合构建微服务、内部 API 服务及大型后端系统。项目还提供 kratos-layout 参考模板,包含分层架构、依赖注入和代码生成示例,可作为新项目的脚手架。需要注意的是,Kratos 主要解决服务端基础架构问题,并不直接提供完整的用户中心、权限管理或管理后台。

项目地址:github.com/go-kratos/kratos

Kratos 的设计核心是:框架提供统一接口和基础机制,具体基础设施通过标准库、独立 Go Module 或外部服务接入。它不是开箱即用的完整业务后台,也不会强制绑定数据库、缓存或注册中心。

功能模块 核心技术 / 依赖 实现方案
HTTP 服务 net/http、Kratos HTTP Transport 封装 HTTP Server、路由、请求上下文和中间件
gRPC 服务 google.golang.org/grpc 基于 gRPC Server、Interceptor 和 Protobuf 生成代码
API 定义与代码生成 Protobuf、protoc、protoc-gen-go、Kratos CLI 先定义 .proto,再生成请求结构、客户端及服务端接口
依赖注入 Google Wire(脚手架常用) 在启动阶段组装 Repository、Service、Transport 等对象
日志 Kratos Log 接口、Go log/slog 统一日志接口,具体输出后端可以替换
请求校验 Protobuf 校验规则、Validate Middleware 根据请求结构执行参数校验,失败时返回统一错误
身份认证 JWT Middleware(Contrib) 校验 Token、提取身份信息;用户登录和 Token 签发由业务实现
授权 Casbin -
权限控制 Middleware、业务授权逻辑 在接口层进行访问控制;复杂 RBAC 需要自行集成授权组件
链路追踪 OpenTelemetry 通过 Middleware 传播 Trace Context,采集跨服务调用链
指标监控 OpenTelemetry Metrics、Prometheus 等 采集请求数量、耗时、错误率等指标,并接入监控系统
配置管理 Kratos Config、YAML 等 统一加载配置;远程配置通过独立适配模块(Apollo、etcd、Nacos、Consul)接入
服务注册与发现 registry 接口、etcd / Consul / Nacos 等 实现注册、服务发现和实例变更监听
限流与熔断 Kratos Middleware 服务端限流、客户端熔断;分布式限流通常需要额外实现或集成
错误处理 Kratos Errors、HTTP/gRPC 状态映射 统一错误码和错误信息,映射为协议对应的响应
编码与序列化 JSON Codec、Protobuf 统一请求和响应编码,可扩展其他 Codec
数据持久化 自选 SQL 驱动、数据库或 ORM Kratos 不内置业务 Repository,应用自行实现数据访问层
  • Transport 层:HTTP / gRPC · Middleware · API 校验
  • Service 层:业务逻辑 · 认证授权 · 错误处理
  • Data / Repository 层:数据库 · 缓存 · 外部 API · 消息队列
  • 基础设施:配置、日志、指标、链路追踪、服务发现

业务层依赖抽象接口,基础设施层负责具体实现,启动入口负责依赖组装:

type UserRepository interface {
    Create(ctx context.Context, name string) error
}

// ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----

// 用户业务逻辑
type UserService struct {
    repo UserRepository
}

func NewUserService(repo UserRepository) *UserService {
    return &UserService{repo: repo}
}

func (s *UserService) CreateUser(
    ctx context.Context, name string,
) error {
    return s.repo.Create(ctx, name)
}

// ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----

type MySQLUserRepository struct {
    db *sql.DB
}

func (r *MySQLUserRepository) Create(
    ctx context.Context, name string,
) error {
    _, err := r.db.ExecContext(
        ctx,
        "INSERT INTO users (name) VALUES (?)",
        name,
    )
    return err
}

Jupiter

注意:这个项目 2024 年开始就不怎么活跃了。

Jupiter 是斗鱼开源的 Go 微服务治理框架,项目地址:douyu/jupiter。它不仅提供 HTTP、gRPC 等服务开发能力,更注重微服务在生产环境中的运行、监控与治理,适用于中大型后端系统和分布式业务平台。

Jupiter 的核心功能包括:服务通信与治理,支持 HTTP、gRPC、服务注册发现、负载均衡、限流、超时和重试等机制;可观测性,提供统一日志、指标采集、分布式链路追踪和错误处理能力;配置管理,支持配置驱动的组件初始化与运行时管理;开发工具链,提供项目脚手架、标准化项目模板和开发调试工具,降低项目搭建与维护成本。

其设计理念是以应用为中心,对常用第三方组件进行统一封装,减少基础设施差异对业务代码的影响,并将监控、配置和治理能力整合到应用运行时中。

适用场景: 需要统一技术栈、完善可观测性和服务治理能力的 Go 微服务体系。相比 Gin、Echo 等侧重 HTTP 请求处理的 Web 框架,Jupiter 的定位更偏向企业级微服务基础设施。代价是引入的组件和治理体系更多,轻量级单体应用未必需要完整采用。

go-zero

其作者在知乎上比较活跃:万俊峰Kevin, Title 是晓黑板 CTO。

go-zero 是一个基于 Go 语言开发的开源微服务框架,旨在帮助开发者快速构建高性能、高可用、易于维护的分布式系统。它提供 API 网关、RPC 服务、服务发现、负载均衡、限流熔断、超时控制、缓存、链路追踪等能力,覆盖微服务从开发到运行的主要环节。

go-zero 的核心特点是 API 定义驱动开发:开发者可以通过 .api 文件描述 HTTP 接口,并使用 goctl 自动生成路由、控制器、逻辑层及相关代码;对于 RPC 服务,则可通过 Protocol Buffers 定义接口并生成代码,减少重复劳动,统一项目结构。框架内置服务治理机制,能够降低分布式系统的开发与运维复杂度。

在架构设计上,go-zero 强调分层组织、依赖隔离和工程规范,适合构建用户服务、订单系统及其他业务微服务。相比轻量级 Web 框架 Gin,go-zero 提供了更完整的微服务基础设施;但对于简单的单体应用,其整体约束和学习成本也相对更高。

参考资料与拓展阅读

#581 GitHub 搜索技巧

2021-06-30

如何快速的、正确的查询资料是开发者的必备技能。GitHub 是一个主要的资料来源,当然需要掌握其用法才行。
除了要知道搜索什么英语术语之外,还有一些别的辅助技能,可以有效的提升 GitHub 搜索效率。

#579 Windows 10 在磁贴中新建快捷方式

2021-06-27

一般安装的软件都可以在开始菜单的 “所有应用” 中看到,选 “固定到开始屏幕” 就行了。

不过,那些 Portable 的绿色软件,如果要放进去怎么弄呢?

  1. 创建快捷方式(我一般直接发送快捷方式到桌面)
  2. 将快捷方式复制到 C:\ProgramData\Microsoft\Windows\Start Menu\Programs\
    我一般会改个名,比如:qq.exe => QQ
  3. 现在会发现 所有应用 里面出现了新增的那个快捷方式
  4. 然后,就是固定到开始屏幕就行了。

#578 小米路由器局域网不能互通

2021-06-27

同一个 WiFi 内,笔记本和台式机无法 Ping 通。

虽然觉得可能性非常小,但还是关闭防火墙试了一下,果然没用。

最后在路由器上下工夫,经过两天的试验,发现可能和小米路由器有关系。

如果发现连接不上了,切换一下 WiFi 加密方式,似乎就正常。

也可能是断开重启的功劳。

总之,不知道原因。