2024年9月23日星期一

Retrieving Secret Values Using REST Services in Infisical

Infisical

Infisical is the open source secret management platform that developers use to centralize their application configuration and secrets like API keys.

What Attracts Me Most: The Ability to Self-Host and a Community Edition That Fully Meets Personal Needs

This article simply introductions how to configure and obtain new credentials.

Generate ClientId and ClientSecret

Go to your Infisical dashboard page, and you will see the "Access Control" menu on left panel.

Click in sequence: "Access Control" -> "Machine identities" -> "Create Identify",enter the "Name" and select the "Role", Finally, click the "Create" button to enter the configuration page.

Infisical_dashboard
The configuration page you can confiure token expire time, or trust Ips

On the confiuration page, you can confiure the token expiration time or the trusted IPs.
You can also keep all setting at their default, click the "Configure" button.

machine_configure

Return to the Machine Identities list page, click the key icon button on the right, and you will see the Client ID, then, click the "Create" button to generate the Client Secret.

machine_clientsecret
Finally, Copy the Client ID and Client Secret to secure location. Be careful, the Client Secret will only be displayed once, if you lose it,you will have to regenerate it.

Attach the Machine Identities to The Project

Return to the Infisical dashboard page, and click the "Add new Project" button to create a test project.

Click the "Explorer" button to enter the "test project", click in sequence, "Access Control" -> "Machine Identities" -> "Add identity", Select the machine identities you previously created, and choose the role "Developer", finally to the "Create" button.

machine_attach

Obtain accessToken using ClientId and ClientSecret

Now we have the ClientID and the ClientSecret, the next step is to request an accessToken from the Infisical server using them.

$ curl --request POST \
  --url https://<your infisical host>/api/v1/auth/universal-auth/login \
  --header 'Content-Type: application/json' \
  --data '{
  "clientId": "<Client ID>",
  "clientSecret": "<Client Secret>"
}'
{
  "accessToken": "eyJhbGciOiJ...........w8KsMTs",
  "expiresIn": 2592000,
  "accessTokenMaxTTL": 2592000,
  "tokenType": "Bearer"
}

Retrieving Secret Value Using AccessToken

# workspaceId, you can find it in the browser's URL
# secretKey, the secret key
# environment, dev or prod, maybe more
# secretPath, the secret directory
$ curl --request GET \
  --url https://<your infisical host>/api/v3/secrets/raw/<secretKey>?workspaceId=66f10299543f9f3255dfba57&environment=dev \
  --header 'Authorization: Bearer <your access token>'
{
  "secret": {
    "_id": "66f11438543f9f3255dfc08f",
    "version": 1,
    "workspace": "66f10299543f9f3255dfba57",
    "type": "shared",
    "environment": "dev",
    "secretKey": "MY_PASSWORD",
    "secretValue": "123321",
    "secretComment": ""
  }
}

Conclusion

REST services are more universal, as they can be implemented in any language, and of course, different SDKs can be used according to one's enviroment. In summary, this is a process of authentication to obtain the secret value, which is sufficient to meet my normal needs.

For more details, please refer to the "Reference" section.

Reference

2024年7月29日星期一

一种 Key-Value 的数据表扩展字段 bizExtInfo 的存取方式

1. 背景

当在数据库中设计表结构时,通常会预留个 扩展字段(biz_ext_info),防止后续因需求变化导致模型频繁变更的问题,这个 扩展字段(biz_ext_info) 通常会设置较大的可变字符串,如下:

CREATE TABLE `xxxxxx` (
  ...
  ...
  `biz_ext_info` varchar(2000) DEFAULT NULL COMMENT '扩展信息',
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='xxxxxx'
;

大部分人的做法会存储 JSON 字符串,存取时都会有个 JSON 解析的过程,同时数据显示也并不直观,下面是通过一种方式让 扩展字段(biz_ext_info) 里存储的数据以一种 Key-Value 的方式存储。

biz_ext_info

如上图所示,当查看 bizExtInfo 时,就类似于表字段+值的方式,相对于 JSON字符串 在查看或者读取使用时将会方便很多。

2. 实现

主要通过两个方法实现:

  • public static String map2string(Map<String, String> map)
  • public static Map<String, String> string2map(String str)

2.1. 存储

在保存数据库对象,这里以 Record 举例,使用 map2string 方法,将 map 转成 string 存储到数据库中

Map<String, String> map = Maps.newHashMap();
map.put("FLAG", "1312");
map.put("AllowPAY", "CHB");
record.setBizExtInfo(MapUtil.map2string(map));

2.2. 读取

从数据库中读取出来,使用 string2map 转成 map,由于 Record 对象里 bizExtInfo 属性定义的是字符串类型,通常会在 Record 类扩展一个方法,如 fetchBizExtInfo(String key)

public class Record {
    ......
    ......
    private String bizExtInfo;

    public String fetchBizExtInfo(String key) {
        Map<String, String> bizExtInfoMap = MapUtil.string2map(bizExtInfo);
        return bizExtInfoMap.get(key);
    }
}

3. 源码

2024年5月27日星期一

Google Github Gitlab SSO 配置获取

SingleSignOn

单点登录(Single Sign-On, SSO) 是一种用户认证过程,它允许用户使用一个单一的身份凭证(如用户名和密码)来访问多个独立的软件系统。SSO 通过集中管理用户身份和认证过程,提高了用户体验和系统安全性,减少了用户记住多个密码的负担。

本片文章将介绍常用的单点登录平台的配置

Githb

登陆进入Github个人首页,点击右上角 个人图标,选择 Settings 菜单,进入设置页面

sso_github_1

选择最下面的 Developer settings 开发者设置菜单

sso_github_2

选择左侧 OAuth Apps 菜单,点击右侧 New OAuth App 新建一个 OAuth 应用

sso_github_3

输入 Application name,和 Homepage URL 主页地址,Authorization callback URL 授权的回调地址,正常回调地址的路径根据自己的应用决定,这里的 /api/v1/sso/github 只是一个例子,最后点击 Register application 注册应用

sso_github_4

注册完成后会跳转到 OAuth app 的详情页面,点击 Generate a new client secret 生成一个客户端密钥,此时已经完整的获取了 CLient IDClient secrets

sso_github_5

Google

进入 Google Cloud 控制台页面,在上面搜索框搜索 Credentials 关键字,选择 Credentials

sso_google_1

点击 创建凭据 - OAuth 客户端 ID,跳转到下一页面

sso_google_2

应用类型选择 Web应用,输入 名称,在 已获授权的重定向URI 中填入你的回调授权地址,如我的 https://www.example.com/api/v1/sso/google,最后点击 创建 按钮

sso_google_3

创建完成后,跳转到下一页会弹出 Client ID 和 Client Secrets

sso_google_4

Gitlab

进入 Gitlab 首页,点击左侧头像,选择 Edit profile 菜单

sso_gitlab_1

将页面拉到最下面,点击左侧 Applications 菜单,进入应用列表页面,点击右侧 Add new application 创建一个新应用

sso_gitlab_2

输入应用的名称 Name,重定向地址 Redirect URI,在 Scopes 里选中 read_user,最后点击 Save application 创建应用

sso_gitlab_3

创建完成后,在下一个页面就可以看到生成的 Client ID (Application ID)Client Secret (Secret)

sso_gitlab_4

2024年5月6日星期一

AI故障排除:Failed to initialize NVML: Driver/library version mismatch

nvidia-gpu

故障描述

在使用 GPU 开发和训练AI程序时,可能会遇到这样的问题,nvidia-smi 命令识别 GPU 昨天好好的,今天就突然出错了

$ nvidia-smi
Failed to initialize NVML: Driver/library version mismatch

这个问题的原因是 NVIDIA 驱动库的版本与系统内核模块不一致。要修复这个问题,需先删除当前的 nvidia 驱动程序,并重新安装正确的 NVIDIA 驱动程序版本就可以解决。

修复步骤

检查内核版本

检查显卡驱动程序使用的内核版本

$ cat /proc/driver/nvidia/version
NVRM version: NVIDIA UNIX x86_64 Kernel Module  535.171.04  Tue Mar 19 20:30:00 UTC 2024
GCC version:  gcc version 11.2.0 (Ubuntu 11.2.0-19ubuntu1)

NVRM版本内核模块为 535.171.04,系统内核为22.04

删除 NVIDIA 驱动

运行以下命令,删除包括 nvidia-common 在内的所有 NVIDIA 软件包。

$ sudo apt purge nvidia-* 
$ sudo apt purge libnvidia-*

执行完毕后,在使用以下命令检查是否还有遗留

$ dpkg -l | grep -i nvidia

查找可用的驱动版本

使用Ubuntu自带的驱动管理工具 ubuntu-drivers devices 来查询当前版本Ubuntu推荐的驱动。

$ ubuntu-drivers devices
== /sys/devices/pci0000:00/0000:00:09.0 ==
modalias : pci:v000010DEd00001EB8sv000010DEsd000012A2bc03sc02i00
vendor   : NVIDIA Corporation
model    : TU104GL [Tesla T4]
driver   : nvidia-driver-418-server - distro non-free
driver   : nvidia-driver-470 - distro non-free
driver   : nvidia-driver-470-server - distro non-free
driver   : nvidia-driver-535 - distro non-free recommended
driver   : nvidia-driver-545 - distro non-free
driver   : nvidia-driver-535-server - distro non-free
driver   : nvidia-driver-450-server - distro non-free
driver   : xserver-xorg-video-nouveau - distro free builtin

输出结果如上,一行中出现了“recommended”二字,说明系统推荐了这个驱动,即nvidia-driver-535。

安装正确的驱动程序

要安装推荐的驱动程序,请运行以下命令。

$ sudo apt install nvidia-driver-535

另外,您还可以执行以下命令来自动安装推荐版本的驱动程序。此时,机器上会自动安装上述推荐版本的驱动程序。

$ sudo ubuntu-drivers autoinstall

重新启动系统

重新启动计算机以使更改生效。

$ sudo reboot

验证问题是否修复

重启后输入以下命令测试驱动安装。如下图所示,可以看到推荐版本的驱动安装成功。

$ nvidia-smi

nvidia-smi

2024年4月17日星期三

字幕生成新招 如何将 OpenAI Whisper 应用于视频字幕制作

上一篇文章 <<走进 OpenAI Whisper 开源语音识别技术>> 介绍了如何使用 whisper 做音频识别,同时可以生成 音轨文件,本章将介绍如何使用生成的 音轨文件 做视频字幕。

1. 准备

2. 使用 FFmpeg 与 SRT 文件做视频烧录

先看一下 srt 文件内容,可以发现是标准的音轨文件,段、时间与内容

1
00:00:00,000 --> 00:00:03,840
you know, meeting with startups and there's not a startup right now out there that is not applying

2
00:00:03,840 --> 00:00:09,200
these AI generative models, these large language models to every interesting problem of the sun.

使用如下 FFmpeg 命令将原视频与 srt 文件烧录到一起

$ ffmpeg -i 9s.mp4 -vf "subtitles=9s.srt" -c:v libx264 -preset medium -c:a copy output.mp4

最后得到带字幕的视频,如下:

注意,上面的是烧录操作,意味着字幕添加到视频中后,字幕就改不了了,除非重新操作

3. 使用播放器VLC加载VTT文件

视频文件与字幕文件分离,可以随时更改字幕文件。这里不局限于使用 VLC 播放器,大部分播放器都支持加载字幕文件。

如果字幕文件与视频文件在同一目录,且名称一样,后缀不一样,如 9s.mp4 与 9s.vtt,播放器会自动加载字幕,srt 文件也适用。

手动加载字幕的前提是视频与字幕文件名称不一样,或者不在同一位置,此时需要手动加载。

20240426153303

4. 结论

尽管有很多成熟的产品可以实现视频字幕,大部分视频编辑软件可以实现更为强大的能力,这里纯属个人好奇使用,不做他论。

走进 OpenAI Whisper 开源语音识别技术

openai-whisper.webp

OpenAI 在 GitHub 上发布的 Whisper 是一个自动语音识别(ASR)系统。Whisper 是一个端到端的深度学习模型,它对音频片段进行处理,并预测对应的文本输出。

Whisper 个人觉得是目前免费做语音识别最好的系统,使用它的理由:

  1. 免费,开放源代码,意味着可以自由使用,包括商业化。
  2. 在数据训练的大模型基础上,识别任务上变现出色,背景噪音的情况下,也有稳定的表现。
  3. 语言识别模型可自由选择下载,意味着可以离线使用,只要你的机器硬件足够高,识别速度是非常快的。
  4. 多语言能力以及翻译能力,支持多种语言的音频,同时也支持翻译成英文,目前仅支持英文
  5. 可以作为命令行工具使用,也提供相关的 python 接口可供编程的能力

下面介绍安装和基本使用方法

安装

$ pip install git+https://github.com/openai/whisper.git
$ sudo apt update && sudo apt install ffmpeg

这里安装了 whisper 的 python 库,同时也需要安装 ffmpeg,因为 whisper 在处理音频文件时,会用到 ffmpeg 来进行音频解码和转码。

使用

Whisper 安装好后,提供了两种使用方式,即 终端使用 和 编程使用。

这里准备了一个音频素材,从 youtube 下载了一段 bbc 的视频,使用 ffmpeg 做了音频提取得到了一个 9秒的音频片段。

关于如何使用 ffmpeg 提取音频,参考文章 音视频处理工具 FFmpeg 的 TOP 10 常用场景

视频链接 ????
音频链接 ????

编程使用

这里使用 medium 模型,模型大小不到2G,初次使用会下载此模型,下载的路径是 ~/.cache/whisper

import whisper

model = whisper.load_model("medium")
result = model.transcribe("dataset/9s.wav")
print(result["text"])
 You know, meeting with startups and there's not a startup right now out there that is not applying these AI Generative models these large language models to every interesting problem of the sun

这里只是简单输出语音识别后的文字,更多的API,如生成不同格式的文本,见官方文档

终端使用

whisper-help.webp

语音转文本

# 使用 medium 模型识别音频,生成 json、srt、tsv、txt、vtt 文件
whisper --model medium dataset/9s.wav

上面的命令会将识别的音频输出到控制台,同时生成带时间刻度的5个文本文件,当然也可根据自己的需求指定要生成的文件格式。

  • 9s.json json格式的文本
  • 9s.srt 文本文件格式,用于存储视频文件的字幕信息
  • 9s.tsv 用于存储表格数据,类似于 CSV
  • 9s.txt 简单文本
  • 9s.vtt 文本文件格式,用于存储视频文件的字幕信息

语音转文本(翻译)

# 带翻译功能,但目前只能讲目标语言翻译到"英文"
whisper --model medium dataset/9s.wav --task translate

结论

OpenAI Whisper 可以说应该是目前最好的 ASR,基于已训练的模型可以自动识别语音,同时支持翻译能力。如果产品级使用,还需要解决模型加载速度以及RT时长的问题。

Reference

如何使用 Python rich 库让你的终端输出更加丰富多彩

python_rich.webp

Python 的 rich 库是一个用于在终端中创建富文本和美观格式的库。它可以用来打印彩色文本、表格、进度条等,使得命令行界面更加生动和用户友好。

以下是如何安装和使用 rich 库的一些基础示例。

1. 使用 pip 安装

$ pip install rich

确保你的 Python 版本至少是 3.6.1,这是 rich 库所要求的最低版本

2. 基本使用

下面列出基本常规的使用案例,rich 功能不局限于此,更多如渲染 markdowntree 或 输出代码语法高亮等功能,可参考 官方文档

2.1. 打印彩色文本

from rich import print

print("[bold red]Hello[/bold red], [green]World![/green]")

python_rich_color_text.webp

这个功能类似于 shell 中定义颜色文本输出,可参看 Shell技巧#终端使用色彩字体

2.2. 创建表格

酷炫的功能,终端可以使用表格展示数据,实用性很强

from rich.table import Table
from rich.console import Console

console = Console()

table = Table(show_header=True, header_style="bold blue")
table.add_column("Date", style="dim", width=12)
table.add_column("Title")
table.add_column("Production Budget", justify="right")
table.add_column("Box Office", justify="right")

table.add_row("Dec 20, 2019", "Star Wars: The Rise of Skywalker", "$275,000,000", "$375,126,118")
table.add_row("May 25, 2018", "[red]Solo[/red]: A Star Wars Story", "$275,000,000", "$393,151,347")
table.add_row("Dec 15, 2017", "Star Wars Ep. VIII: The Last Jedi", "$262,000,000", "$1,332,539,889")

console.print(table)

python_rich_table.webp

2.3. 进度条示例

from rich.progress import Progress
import time

with Progress() as progress:
    task1 = progress.add_task("[red]Downloading...", total=1000)
    task2 = progress.add_task("[green]Processing...", total=1000)
    task3 = progress.add_task("[cyan]Cooking...", total=1000)

    while not progress.finished:
        progress.update(task1, advance=5)
        progress.update(task2, advance=3)
        progress.update(task3, advance=9)
        time.sleep(0.02)  # 代表实际工作的代码

python_rich_progress.gif

2.4. 使用日志记录

from rich.logging import RichHandler
import logging

# 配置日志记录
logging.basicConfig(
    level="NOTSET",
    format="%(message)s",
    datefmt="[%X]",
    handlers=[RichHandler()]
)

logger = logging.getLogger("rich")

logger.info("这是一条信息日志")
logger.warning("警告!存在潜在问题")
logger.error("这是一条错误日志")

python_rich_log.webp

3. Rich cli

Rich 从 python 库引申了终端的 rich-cli 工具,安装(brew install rich)好可以直接在 shell 终端使用,几个比较使用的功能

$ rich README.md
$ rich data.json
$ rich notebook.ipynb
$ rich loop.py

Reference

2024年3月28日星期四

图片处理工具 ImageMagic 的 TOP 10 实用场景

imagemagic

ImageMagick 是一个功能丰富的命令行工具,它允许用户创建、编辑、合成和转换数字图像。它能够处理各种格式的图像,包括常见的JPEG、PNG、GIF、TIFF以及许多其他格式。此外,ImageMagick提供了强大的API,可供各种编程语言使用,使其成为自动化图像处理任务的理想选择。

请注意,从ImageMagick 7开始,convert命令已经被magick命令所替代。在新版本中,您可以通过直接使用magick命令来代替convert

1. 图像格式转换

对于 png、jpg 图片格式因为大小的问题而不利于网络传输,转成 webp 格式,调整下质量,去除元数据可以大大减少其体积

# png 转 webp,-strip 删除元数据,调整图像质量
$ magick input.png -strip -quality 80 output.webp

2. 调整图像大小

将图像的大小调整为800x600像素

$ magick input.jpg -resize 800x600 output.jpg

3. 裁剪图像

从原图中裁剪出300x300像素的区域,起始点为(100,100)

$ magick input.jpg -crop 300x300+100+100 output.jpg

4. 旋转图像

将图像顺时针旋转90度

$ magick input.jpg -rotate 90 output.jpg

5. 添加文字水印

在图像上添加文字水印

$ magick input.jpg -font Arial -pointsize 20 -draw "text 10,20 'Watermark'" output.jpg

6. 调整图像质量

调整JPEG图像的质量至75%

$ magick input.jpg -quality 75 output.jpg

7. 合并图像

# 水平合并两张图像
$ magick image1.jpg image2.jpg +append output.jpg
# 垂直合并两张图像
$ magick image1.jpg image2.jpg -append output.jpg

8. 色彩调整

提高图像的亮度

$ magick input.jpg -modulate 110,100,100 output.jpg

9. 创建GIF动画

从多张图像创建GIF动画

$ magick -delay 20 -loop 0 image1.jpg image2.jpg image3.jpg output.gif

10. 图像模糊

对图像应用高斯模糊效果

$ magick input.jpg -blur 0x4 output.jpg

总结

因为比较懒,同时也比较喜欢极客的做事方式,能不安装的软件就安装,用一条命令解决的事情,为什么要安装 GUI 界面程序完成。熟悉命令使用方式的同时,也能理解 ImageMagic 能做什么,生产型应用的集成使用 ImageMagic 能完成什么。

2024年3月27日星期三

音视频处理工具 FFmpeg 的 TOP 10 常用场景

2000px-FFmpeg_Logo
FFmpeg 是一个开源的多媒体框架,它包含了一系列用于处理视频、音频和其他多媒体文件和流的库和工具。在LGPL或GPL许可下发布,可被用于个人和商业项目中。

FFmpeg能够处理几乎所有的视频和音频格式,它支持转换格式、编解码、录制、流媒体处理等功能。FFmpeg被广泛用于视频转换和流媒体解决方案中,如在线视频平台、转码服务以及个人视频处理等场景。

下面将以终端命令的形式介绍 FFmpeg 的常规使用场景,但 FFmpeg 不局限于在终端命令上使用,同时也提供各种编程语言的库,可程序集成调用使用。

ffmpeg 参数很多,下面不纠结解释各个参数的明细说明

1. 格式转换

# 视频转换,avi 转 mp4
$ ffmpeg -i input.avi output.mp4

# 音频转换,mp3 转 wav
$ fffmpeg -i input.mp3 output.wav

# 视频转GIF
$ fffmpeg -i input.mov -r 15 file.gif

2. 提取视频中的音频

$ ffmpeg -i input.mp4 -vn output.mp3

3. 分段裁剪视频

# -ss 哪里开始,-to 哪里结束
$ ffmpeg -i input.mp4 -ss 00:00:10 -to 00:00:20 -c copy output.mp4

4. 视频压缩大小

$ ffmpeg -i input.mp4 -b:v 1M -b:a 128k output.mp4

5. 给视频添加水印

# 使用图片水印,右下角间隔5像素
$ ffmpeg -i input.mp4 -i watermark.png -filter_complex "W-w-5:H-h-5" output.mp4

6. 生成视频缩略图

$ ffmpeg -i input.mp4 -vf "thumbnail,scale=320:180" -frames:v 1 output.jpg

7. 视频分辨率

# 分辨率小于原分辨率,能调大但会模糊
$ ffmpeg -i input.mp4 -s 1280x720 output.mp4

8. 添加字幕到视频

# 这种是字幕烧录到视频的方式,不可还原,即不能提取视频的字幕
$ ffmpeg -i input.mp4 -vf "subtitles=subtitle.srt" -c:v libx264 -preset medium -c:a copy output.mp4

9. 提取某帧为图片

ffmpeg -i input.mp4 -ss 00:00:10 -frames:v 1 output.png

10. 视频分片与重组

视频分片常用于HTTP实时流式传输,因为不需要下载整个视频即可逐段播放,m3u8 文件保存播放的 ts 地址,分片加载,减少了缓冲时间。

10.1. 视频分片

# 将生成 m3u8 文件已经对应的 ts片段文件
$ ffmpeg -i output.mp4 -codec: copy -start_number 0 -hls_time 10 -hls_list_size 0 -f hls output.m3u8

尝试将视频源文件mp4、m3u8以及ts文件放到服务器路径中,使用 http://127.0.0.1:8080/output.m3u8 的方式加载播放

10.2. 分片重组

既然可以将视频分片,能否通过分片的 m3u8 文件,重新合并为视频源文件

$ ffmpeg -i http://127.0.0.1:8080/output.m3u8 -c copy -bsf:a aac_adtstoasc output.mp4

总结

偶尔做一些视频编辑,会用到很多大型视频编辑器,但往往对于短平快的操作,可以直接使用 FFmpeg 完成,接触下来,FFmpeg 功能十分强大,参数众多,可玩性很足。可以结合企业场景,使用编程的方式处理音视频,且大多数产品也是这样做的。

2024年1月17日星期三

分享使用多年简单高效的 spring boot 模板工程结构

尽管目前市场主流编程语言有很多,但 Java 仍然是企业的使用首选,不仅是成长多年,积累了不少 Coder,也在于丰富的开源库,而 spring 全家桶仍然非常流行,本篇文章结合作者多年使用,总结的一个简单的 spring boot 模板结构,具有以下优缺点:

优点:

  • 干净清爽,不依赖任何第三方库,适合手工码字人
  • 一个的业务处理入口(Controller),避免入口泛滥在应用中的各个地方
  • 异常处理、响应结果、摘要日志、鉴权部分的预留等等,同样是避免切面膨胀
  • 研发只需关注业务部分代码的开发,不需要管异常、日志、鉴权等非主流程处理的代码
  • 自定义空间大,模板结构保存很多预留位,可自定义扩展

缺点:

  • 适用于处理通用HTTP业务请求,JSON格式的请求响应体,对于websocket或上传下载等需另行定义处理
  • 业务请求的配置路径在 xml 文件中完成,多人开发容易造成代码冲突

1. 类结构图

1.1. 领域对象

下图主要是领域对象的定义,涵盖异常、错误码与服务结果,错误级别、错误码都是为业务异常服务,出现异常的情况,最终会以正常状态服务结果返回,而不是异常堆栈的直接抛出。

20240118101728

为了更快的创建出模板结构,上面数字代表创建顺序,详细的代码可直接点击查看:

  • CommonResultCode,通用的结果定义,用于约束返回内容
  • ErrorCodeConstants,错误码常量定义,应结合错误码规范,其中包含错误码前缀、错误级别与业务域的定义
  • CommonResultCodeEnum,错误码枚举类的定义,因实现了CommonResultCodeErrorCodeConstants,只需定义自己的四位错误码
  • ServiceResult,响应结果,贯穿整条业务请求,其中定义约束了返回结构,应遵循各自的前后端交互规范
  • AbstractBizException,抽象的业务异常对象,由自定义异常继承
  • CustomBizException,自定义的业务异常,需继承AbstractBizException
  • AssertUtils,断言工具类,与AbstractBizException绑定,业务开发中不必if...else...判断,使用此工具直接抛

完成上面领域对象的定义,在 applicationContext.xml 中配置个异常的 Bean 对象,具体可以看AssertUtils类注释,第一步完成。

<bean class="com.xxx.xxx.exception.AssertUtils">
    <property name="exceptionClassName" value="com.xxx.xxx.exception.CustomBizException"/>
</bean>

1.2. 请求委派

领域对象贯穿业务请求的生命周期,对于每个请求的的扭转委派,如下图定义:

20240118135016

尽管已经最小化,为了简单,仍然用了一些工具类的包,提前配置在 pom.xml 文件中,如下:

<!-- JSON格式处理 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.65</version>
</dependency>

<!-- 工具包 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.8.1</version>
</dependency>

<!-- 日志 -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>2.0.10</version>
</dependency>

按上图步骤,依次创建的类如下:

至此所有模板代码已创建完成,下面看如何使用。

2. 模板使用

2.1. 编写服务

DelUser,继承AbstractServiceCallback类,必需要实现executeService方法,beforeServiceafterService 可选

import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Component;

@Component("deleteUser")
public class DelUser extends AbstractServiceCallback<ServiceRequest, ServiceResult<String>> {

    /**
     * 前置处理(可选的方法),生命周期在 executeService 执行之前
     * 可以做一些参数校验等操作
     *
     * @param request 服务请求对象
     */
    @Override
    public void beforeService(ServiceRequest request) {
        super.beforeService(request);

        // 参数验证
        JSONObject postJson = request.parseData(JSONObject.class);
        AssertUtils.notNull(postJson, CommonResultCodeEnum.PARAM_ILLEGAL, "post data is null");

        Long id = postJson.getLong("id");
        AssertUtils.notNull(id, CommonResultCodeEnum.PARAM_ILLEGAL, "id is null");
    }

    @Override
    public ServiceResult executeService(ServiceRequest request) {
        // 获取返回对象,最终将在 result 的 T data 中呈现
        String resultData = "ok";

        return ServiceResult.valueOfSuccess(resultData);
    }

    /**
     * 后置处理(可选的方法),生命周期在 executeService 执行完后
     * 可以做回收的操作
     *
     * @param request 服务请求对象
     * @param result {@link ServiceResult}
     */
    @Override
    public void afterService(ServiceRequest request, ServiceResult result) {
        super.afterService(request, result);
    }
}

2.2. 注册服务

将上面的服务注册到request-mapping.xml文件中,下面的 entry key 就是要请求的路径,如/api/user/delete

<bean id="domainServiceProcess" class="com.cainiao.moore.template.DomainServiceProcessImpl">
    <property name="serviceMap">
        <map>
            <entry key="api_user_delete"  value-ref="deleteUser"/>
        </map>
    </property>
</bean>

2.3. 服务访问

启动 spring boot 应用, 使用 curl 或者 postman 这样的工具发起请求

20240118145639

3. Conclusion

整个服务模板,搭建起来废点事,但实际使用中,会发现非常简单,继承服务回调类,注册服务,技术只需要在自己的服务中编写业务代码,完全不需要关注日志怎么打,异常怎么处理,上层都已进行了封装。

仁者见仁,智者见智,适合自己的才是最好的

4. 代码及素材

2024年1月9日星期二

如何使用 vscode remote tunnel 远程访问本地环境进行代码开发

server-arch-latest

1. 适合什么人

自由开发者,边旅行边工作的技术人,懒惰的不想背电脑的码农,经常要突然处理的IT社畜。

2. 有什么特点

  1. 性能优势,尽管存在众多在线的IDE,但基于商业化的原则,资源的消耗往往需要付费才能使用。而 vscode remote tunnel 不一样,只要网络正常,使用的是远程本地机器资源,不需要担心性能问题。
  2. 环境一致,不同机器或不同的在线IDE,开发环境往往需要提前配置,包括环境变量、依赖安装等等,往往还不能成功编译运行,这样的问题在 vscode remote tunnel 不存在,可以节省很多维护工作。
  3. 可访问性,任何时间、任何地点、任何设备,网络通畅,只要搭载浏览器的设备即可实现远程办公。

总之,VS Code Remote Tunneling 提供了一种灵活而强大的方式,使远程工作更加流畅和高效,特别对于有远程工作需求或需要访问特定远程资源的开发者来说,这是一个很有价值的工具。

3. 有什么缺点

  1. 机器损耗与电费支出,一台常年不关也不休眠的电脑
  2. 网络问题,遇到网络不通,或网速过慢时,体验不好

4. 使用步骤

整体步骤相对简单,在本地(或者说家里)的电脑上开启 vscode remote tunnel,且保持电脑不关机也不休眠(可调低亮度降低资源损耗以及屏幕的使用寿命),在任何地点的电脑上打开浏览器访问 vscode.dev,使用相同的登陆账号访问本地机器进行开发。

4.1. 开启 vscode remote tunnel

在 vscode 中,cmd + shift + p 调出命令面板,输入 remote tunnel,选择 Turn on Remote Tunnel Access 打开远程隧道。

中途可能会提示你使用 Github 或者 Microsoft 账号授权登陆,按步骤操作即可。开启完成,会提示你复制远程连接,可以复制,通过粘贴到浏览器中打开确定可用,之后忘记连接也没有关系,只要远程访问时保持账号一致,也可以看见开启的 remote tunnel 服务。

vscode remote tunnel

开启完,修改电源选项,避免其休眠或关机,关闭显示器或合上笔记本后盖,保持一直运行。

4.2. 浏览器访问 vscode.dev

在任何地方打开浏览器访问 vscode.dev,点击左下角头像使用 Github 或者 Microsoft 账号授权登陆,点击左侧 remote explorer,在 Tunnels 就能看到远程运行的 vscode remote tunnel 隧道服务的机器,默认就是电脑的名称,双击即可进行远程机器的开发环境。

access remote vscode tunnel

5. 使用方法

打开 vscode.dev 连接上 remote tunnel后,也许不是你希望的应用或目录,可以在菜单里打开 终端Terminal,自由使用命令进行操作,尽管这看起来并不安全,因为只要连接到隧道后,你可以做任何事情。

remote tunnel terminal

至此,可以愉快的远程进行开发啦

Reference

Retrieving Secret Values Using REST Services in Infisical

Infisical is the open source secret management platform that developers use to centralize their application configuration and secrets like...