Tuesday, July 27, 2021

V2EX - 技术

V2EX - 技术


局域网搭建 DNS 服务器,怎么让局域网的服务器、电脑、手机全部生效?

Posted: 27 Jul 2021 04:09 AM PDT

比如

192.168.2.125 www.baidu.com 

我修改路由器上面的 dns,改为我局域网的 DNS 服务器的 IP,没效果

我是想着配置了 DNS,其他电脑就不用手动配置 hosts

安卓不进系统就可以改语言设置吗?

Posted: 27 Jul 2021 04:05 AM PDT

我 pixel 屏幕坏了送修,数据都没动。

看对方发过来修好的照片(锁屏界面),系统语言变成了中文(原来是英文)。

所以是可以在不进系统情况下改语言设置吗?担心猜到了我用的 PIN 码(很简单)

还有换个屏幕为啥要改语言?还是别的什么情况?

现在开发一个低代码工具,会不会晚了?

Posted: 27 Jul 2021 04:03 AM PDT

关于程序员会不会被低代码开发取代,很多 v 友给了我很多很好的回答。

新加入的这个团队领导让我们研究下低代码,刚好在看一些文章,分享下: https://www.zentao.net/redirect-index-19285.html https://developer.aliyun.com/article/778493 https://www.cuelogic.com/blog/low-code-platform

可能我们团队会自己开发一个低代码工具,也不知道会不会起步晚了。 总感觉目前市面的工具不少了………………

好迷茫

阿里云还是 AWS?

Posted: 27 Jul 2021 03:56 AM PDT

有没深度体验过两者区别的大佬,你们怎么选型的呢

镜像讨论:阿里云还是 AWS ?

买白群晖好还是自己倒腾黑群晖好

Posted: 27 Jul 2021 03:40 AM PDT

现在手里有一套 e3 配置 e3 1230 v2 b75 itx 8g 内存 自己倒腾黑群晖的话要买一个 nas 机箱(乔思伯 n1 699 ) 还有一个小电源

看京东白群晖两三千的都有,和黑群晖差别大吗?两千多的那个会卡么

企业证书被封了

Posted: 27 Jul 2021 03:35 AM PDT



一早上起来蒙了,请问有遇到过的吗,我们是打包给客户使用的,然后放二维码在客户首页。

如何提高群晖 NAS 的外网访问速度

Posted: 27 Jul 2021 03:31 AM PDT

暂时没有公网 IP
有一个外网服务器
有一个域名

vim 用久了右手小拇指疼

Posted: 27 Jul 2021 03:28 AM PDT

右手小拇指承受了大量的按键, 搞的现在都不敢用 vim 了,你们的小手指都没问题吗? 还是我代码写多了。

ssh 的私钥并没有放在 ssh-add 的高速缓存里,甚至 ssh-agent.exe 没有启动。为什么还是能正常 git clone?

Posted: 27 Jul 2021 03:20 AM PDT

执行 ssh-add -l 终端输出 The agent has no identities.

C:\Users\MY_USERNAME\.ssh\ 下存放了很多不同网站(比如 github 、gitee 、 公司 gitlab 、自建 gitlab )的公钥私钥对、以及 config 、environment 文件

以前有一次帮同事排查 git clone Permission Denied 的问题,后面帮他启动了 ssh-agent 程序,并使用 ssh-add PRIVATE-KEY-PATH 命令添加了私钥到 ssh-add 的高速缓存里了,再 git clone,成功了。

但是今天发现 ssh-agent 程序不启动也可以正常 git clone,是为什么?求解惑。


另外推荐一个 ssh for Windows 的配置,使用 Git Bash

👉🏻 Setup SSH Authentication for Git Bash on Windows: https://gist.github.com/bsara/5c4d90db3016814a3d2fe38d314f9c23

Python 调用 win32api 时间问题,自认为属于高阶问题

Posted: 27 Jul 2021 02:12 AM PDT

源代码如下:
import win32api
import win32con
import win32gui
import win32ui
1 win32api.SetCursorPos((click_x, click_y))
2 win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0x1, 0, 0, 0)
3 win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0x1, 0, 0, 0)
4 win32api.SetCursorPos((click_x, click_y))
5 win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0x1, 0, 0, 0)
6 win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0x1, 0, 0, 0)
7 win32api.SetCursorPos((click_x, click_y))
8 win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0x1, 0, 0, 0)
9 win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0x1, 0, 0, 0)
上述代码在运行过程中有个奇怪现象,有的时候运行需要 22ms 左右,有的时候却只要 8ms 左右,是什么问题造成如此结果,正常情况下应该都是一样的吧,我将此程序在 windows 系统中的执行优先级设为"实时",出现 22ms 的次数更多。

望有懂得技术大哥帮助小弟解开这个疑惑(不要告诉我百度,百度了没结果)

Python +vue 运维平台, 支持 k8s 管理

Posted: 27 Jul 2021 01:25 AM PDT

最新写了一个运维平台,大家看看有什么不足的地方 https://github.com/small-flying-pigs/devops-api

��‍��PowerProto: gRPC 工具链(protoc, protoc-gen-go)的一键安装与版本控制

Posted: 27 Jul 2021 01:24 AM PDT

goreport.png totalline.png lastcommit.png godoc.png

中文 | English

exmaple.gif

项目地址:🎉 An awesome version control tool for protoc and its related plugins. (github.com/storyicon/powerproto)

PowerProto 主要用于解决下面三个问题:

  1. 降低 gRPC 的使用门槛与使用成本。
  2. 解决 protoc 以及其相关插件(比如 protoc-gen-go 、protoc-gen-grpc-gateway )的版本控制问题。
  3. 高效管理 proto 的编译,实现多平台兼容、一键安装与编译。

🎉 功能

  1. 实现 protoc 的一键安装与多版本管理。
  2. 实现 protoc 相关插件(比如 protoc-gen-go )的一键安装与多版本管理。
  3. 通过配置文件管理 proto 的编译,而非 shell 脚本,提高可读性与兼容性。
  4. 引导式生成配置文件,跨平台兼容,一份配置在多个平台均可以实现一键编译。
  5. 支持批量、递归编译 proto 文件,提高效率。
  6. 跨平台支持 PostAction,可以在编译完成之后执行一些常规操作(比如替换掉所有生成文件中的"omitempty")。
  7. 支持 PostShell,在编译完成之后执行特定的 shell 脚本。
  8. 支持 google api, gogo protobuf 等的一键安装与版本控制。

安装与依赖

  1. 目前版本的 PowerProto 依赖 go 以及 git(未来可能会直接使用 CDN 拉取构建好的二进制),请确保运行环境中包含这两个命令。
  2. protoc的下载源是 Github,PowerProto在下载protoc时尊重 HTTP_PROXYHTTPS_PROXY环境变量,如果遇到网络问题,请自行配置代理。
  3. 在查询protoc的版本列表时,会对github.com使用git ls-remote,如果遇到网络问题,请自行为git配置代理。
  4. 在当前版本,下载和查询插件版本均依赖go命令,所以如果遇到网络问题,请自行配置 GOPROXY环境变量。
  5. 默认会使用 用户目录 /.powerproto作为安装目录,用于放置下载好的各种插件以及全局配置,可以通过 POWERPROTO_HOME环境变量来修改安装目录。
  6. 如果认为powerproto名字太长,可以通过alias成一个更简单的名字来提高输入效率,比如没有人会介意你叫它pp

一、通过 Go 进行安装

直接执行下面的命令即可进行安装:

go install github.com/storyicon/powerproto/cmd/powerproto@latest 

二、开箱即用版本

可以通过 Github Release Page 下载开箱即用版本。

命令介绍

你可以通过 powerproto -h 来查看帮助,比如:

powerproto -h powerproto init -h powerproto tidy -h powerproto build -h powerproto env -h 

它的好处是命令行中的文档永远和你的二进制版本保持一致。而 Github 上的文档可能会一直是对应最新的二进制。

一、初始化配置

可以通过下面的命令进行配置的初始化:

powerproto init 

二、整理配置

可以通过下面的命令整理配置:

powerproto tidy 

它将会从当前目录开始向父级目录搜索名为 powerproto.yaml 的配置文件,并对配置进行读取和整理。

你也可以指定整理哪个配置文件:

powerproto tidy [the path of proto file] 

整理配置主要包含两个操作:

  1. 通过查询,将版本中的 latest 替换为真实的最新版本号。
  2. 安装配置文件中定义的所有依赖。

支持通过 -d 参数来进入到debug 模式,查看更详细的日志。

三、编译 Proto 文件

可以通过下面的命令进行 Proto 文件的编译:

// 编译指定的 proto 文件 powerproto build xxxx.proto  // 编译当前目录下的所有 proto 文件 powerproto build .  // 递归编译当前目录下的所有 proto 文件,包括子文件夹。 powerproto build -r . 

其执行逻辑是,对于每一个 proto 文件,从其文件所在目录开始向父级目录寻找 powerproto.yaml 配置文件:

  1. 对于找到的配置文件,与其中的scope进行匹配,如果匹配则采用。
  2. 检查并安装配置文件中声明的依赖。
  3. 根据配置文件中的pluginsprotocoptionsimportPaths等配置对 proto 文件进行编译。 当所有的 proto 文件都编译完成之后,如果你指定了 -p 参数,还会进行PostActionPostShell的执行。

注意:protoc执行的工作目录默认是proto 文件匹配到的配置文件所在的目录,它相当于你在配置文件所在目录执行 protoc 命令。你可以通过配置文件中的 protocWorkDir 来进行修改。

支持通过 -d 参数来进入到debug 模式,查看更详细的日志。 支持通过 -y 参数来进入到dryRun 模式,只打印命令而不真正执行,这对于调试非常有用。

四、查看环境变量

如果你的命令一直卡在某个状态,大概率是出现网络问题了。 你可以通过下面的命令来查看环境变量是否配置成功:

powerproto env 

示例

比如你在 /mnt/data/hello 目录下拥有下面这样的文件结构:

$ pwd /mnt/data/hello  $ tree ./apis └── hello.proto powerproto.yaml 

powerproto.yaml 的文件内容是(你可以通过 powerproto init 命令很方便的生成配置文件):

scopes:     - ./ protoc: latest protocWorkDir: "" plugins:     protoc-gen-go: google.golang.org/protobuf/cmd/protoc-gen-go@latest     protoc-gen-go-grpc: google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest repositories:     GOOGLE_APIS: https://github.com/googleapis/googleapis@75e9812478607db997376ccea247dd6928f70f45 options:     - --go_out=.     - --go_opt=paths=source_relative     - --go-grpc_out=.     - --go-grpc_opt=paths=source_relative importPaths:     - .     - $GOPATH     - $POWERPROTO_INCLUDE     - $GOOGLE_APIS/github.com/googleapis/googleapis postActions: [] postShell: "" 

在任意目录执行:

powerproto build -r /mnt/data/hello/apis 

你都可以得到编译后的文件

$ pwd /mnt/data/hello  $ tree ./apis ├── hello.pb.go ├── hello.proto └── hello_grpc.pb.go powerproto.yaml 

它相当于你在 powerproto.yaml 所在目录,执行:

$POWERPROTO_HOME/protoc/3.17.3/protoc --go_out=. \ --go_opt=paths=source_relative \ --go-grpc_out=. \ --go-grpc_opt=paths=source_relative \ --proto_path=/mnt/data/hello \ --proto_path=$GOPATH \ --proto_path=$POWERPROTO_HOME/include \ --proto_path=$POWERPROTO_HOME/gits/75e9812478607db997376ccea247dd6928f70f45/github.com/googleapis/googleapis \ --plugin=protoc-gen-go=$POWERPROTO_HOME/plugins/google.golang.org/protobuf/cmd/protoc-gen-go@v1.27.1/protoc-gen-go \ --plugin=protoc-gen-go-grpc=$POWERPROTO_HOME/plugins/google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1.0/protoc-gen-go-grpc /mnt/data/hello/apis/hello.proto 

配置文件

配置文件用于描述编译 proto 文件时,各种依赖的版本以及参数等。

可以方便的通过 powerproto init进行配置文件的初始化。

解释

以下面这份配置文件为例:

# 必填,scopes 用于定义作用域,即当前配置项对项目中的哪些目录生效 scopes:     - ./ # 必填,protoc 的版本,可以填 latest,会自动转换成最新的版本 protoc: 3.17.3 # 选填,执行 protoc 命令的工作目录,默认是配置文件所在目录 # 支持路径中混用环境变量,比如$GOPATH protocWorkDir: "" # 选填,定义依赖的 Git 存储库 # 一般用于公共的 protobuf 库的依赖控制 repositories:     # 定义依赖 27156597fdf4fb77004434d4409154a230dc9a32 版本的 https://github.com/googleapis/googleapis     # 并且定义其名字为 GOOGLE_APIS     # 在 importPaths 中可以通过 $GOOGLE_APIS 来引用它     GOOGLE_APIS: https://github.com/googleapis/googleapis@27156597fdf4fb77004434d4409154a230dc9a32     # 定义依赖 226206f39bd7276e88ec684ea0028c18ec2c91ae 版本的 https://github.com/gogo/protobuf     # 并且定义其名字为 GOGO_PROTOBUF     # 在 importPaths 中可以通过 $GOGO_PROTOBUF 来引用它     GOGO_PROTOBUF: https://github.com/gogo/protobuf@226206f39bd7276e88ec684ea0028c18ec2c91ae # 必填,代表 scope 匹配的目录中的 proto 文件,在编译时需要用到哪些插件 plugins:     # 插件的名字、路径以及版本号。     # 插件的地址必须是 path@version 的格式,version 可以填 latest,会自动转换成最新的版本。     protoc-gen-deepcopy: istio.io/tools/cmd/protoc-gen-deepcopy@latest     protoc-gen-go: google.golang.org/protobuf/cmd/protoc-gen-go@latest     protoc-gen-go-json: github.com/mitchellh/protoc-gen-go-json@v1.0.0     protoc-gen-grpc-gateway: github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway@v2.5.0 # 必填,定义了编译 proto 文件时 protoc 的参数 options:     - --go_out=paths=source_relative:.     - --go-json_out=.     - --deepcopy_out=source_relative:.     - --grpc-gateway_out=.     - --go-grpc_out=paths=source_relative:. # 必填,定义了构建时 protoc 的引用路径,会被转换为 --proto_path (-I) 参数。 importPaths:     # 特殊变量。代表当前配置文件所在文件夹     - .     # 环境变量。可以使用环境变量     # 也支持 $GOPATH/include 这样的混合写法     - $GOPATH     - $POWERPROTO_INCLUDE     # 特殊变量。引用待编译的 proto 文件所在的目录     # 比如将要编译 /a/b/data.proto,那么 /a/b 目录将会被自动引用     - $SOURCE_RELATIVE     # 引用 repositories 中的 GOOGLE_APIS     - $GOOGLE_APIS/github.com/googleapis/googleapis     # 引用 repositories 中的 GOGO_PROTOBUF     - $GOGO_PROTOBUF # 选填,构建完成之后执行的操作,工作目录是配置文件所在目录 # postActions 是跨平台兼容的 # 注意,必须在 powerproto build 时附加 -p 参数,才会执行配置文件中的 postActions postActions: [] # 选填,构建完成之后执行的 shell 脚本,工作目录是配置文件所在目录 # postShell 不是跨平台兼容的。 # 注意,必须在 powerproto build 时附加 -p 参数,才会执行配置文件中的 postShell postShell: |     // do something 

匹配模式与工作目录

在构建 proto 文件时,将会从 proto 文件所在目录开始,向父级目录搜索 powerproto.yaml 配置文件,并与其中的 scope 进行匹配,第一个匹配到的配置,将会被用于此 proto 文件的编译。 在执行 protoc 时(执行 postActions 、postShell 时也是如此),是以配置文件所在目录作为工作目录的,即相当于你在这个目录执行 protoc 命令。

多配置组合

一个配置文件中支持填写多份配置,多份配置之间以 "---" 进行分割。

在下面的示例中,apis1 目录使用的是 v1.25.0 的 protoc-gen-go,而 apis2 目录使用的则是 v1.27.0 的 protoc-gen-go 。

scopes:     - ./apis1 protoc: v3.17.3 protocWorkDir: "" plugins:     protoc-gen-go: google.golang.org/protobuf/cmd/protoc-gen-go@v1.25.0     protoc-gen-go-grpc: google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1.0 repositories:     GOOGLE_APIS: https://github.com/googleapis/googleapis@75e9812478607db997376ccea247dd6928f70f45 options:     - --go_out=.     - --go_opt=paths=source_relative     - --go-grpc_out=.     - --go-grpc_opt=paths=source_relative importPaths:     - .     - $GOPATH     - $POWERPROTO_INCLUDE     - $GOOGLE_APIS/github.com/googleapis/googleapis postActions: [] postShell: ""  ---  scopes:     - ./apis2 protoc: v3.17.3 protocWorkDir: "" plugins:     protoc-gen-go: google.golang.org/protobuf/cmd/protoc-gen-go@v1.27.0     protoc-gen-go-grpc: google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1.0 repositories:     GOOGLE_APIS: https://github.com/googleapis/googleapis@75e9812478607db997376ccea247dd6928f70f45 options:     - --go_out=.     - --go_opt=paths=source_relative     - --go-grpc_out=.     - --go-grpc_opt=paths=source_relative importPaths:     - .     - $GOPATH     - $POWERPROTO_INCLUDE     - $GOOGLE_APIS/github.com/googleapis/googleapis postActions: [] postShell: "" 

PostAction

PostAction 允许在所有的 proto 文件都编译完成之后,执行特定的操作。与PostShell相比,它是跨平台支持的。

为了安全起见,只有在执行 powerproto build时附加上 -p 参数,才会执行配置文件中定义的PostActionPostShell

目前,PostAction 支持下面这些命令:

命令 描述 函数原型
copy 复制文件或文件夹 copy(src string, dest string) error
move 移动文件或文件夹 move(src string, dest string) error
remove 删除文件或文件夹 remove(path ...string) error
replace 批量替换文件中的字符串 replace(pattern string, from string, to string) error

1. copy

用于复制文件或文件夹,其函数原型为:

copy(src string, dest string) error 

为了安全以及配置的兼容性,参数中只允许填写相对路径。

如果目标文件夹已经存在,将会合并。

下面的例子将会把配置文件所在目录下的 a 复制到 b:

postActions:     - name: copy       args:         - ./a         - ./b 

2. move

用于移动文件或文件夹,其函数原型为:

move(src string, dest string) error 

为了安全以及配置的兼容性,参数中只允许填写相对路径。

如果目标文件夹已经存在,将会合并。

下面的例子将会把配置文件所在目录下的 a 移动到 b:

postActions:     - name: move       args:         - ./a         - ./b 

3. remove

用于删除文件或文件夹,其函数原型为:

remove(path ...string) error 

为了安全以及配置的兼容性,参数中只允许填写相对路径。

下面的例子将会删除配置文件所在目录下的 a 、b 、c:

postActions:     - name: remove       args:         - ./a         - ./b         - ./c 

4. replace

用于批量替换文件中的字符串,其函数原型为:

replace(pattern string, from string, to string) error 

其中:

  • pattern 是支持通配符的相对路径。
  • from 是要被替换的字符串。
  • to 是替换为的字符串。

下面的例子将会把 apis 目录以及其子目录下的所有 go 文件中的 ,omitempty 替换为空字符串:

postActions:     - name: replace       args:         - ./apis/**/*.go         - ',omitempty'         - "" 

Windows 11 22000.100 自带 Sandbox 沙盒 用不了

Posted: 27 Jul 2021 01:13 AM PDT

版本 Windows 11 专业工作站版
版本 21H2
安装日期 ‎21/‎6/‎30/‎星期三
操作系统版本 22000.100
体验 Windows Feature Experience Pack 421.18901.0.3

Sandbox 能打开,但是打开之后一直闪 什么操作都做不了

腾讯云续费,有什么优惠的渠道吗?

Posted: 27 Jul 2021 12:58 AM PDT

手上一台 4c8g5M,快到期了,刚去后台看了下,续费的原价大概¥ 4000 +,付款页面无任何优惠券提示。
之前有加过一些所谓的代理,但是得到的回复大多是首年可以有比较大的折扣,续费的话,只能原价续费然后给一点点返点。

react 框架下,有没有好用的 contextmenu 解决方案?

Posted: 27 Jul 2021 12:21 AM PDT

本来是想用 "react-conextmenu",结果发现,停止维护了

https://github.com/vkbansal/react-contextmenu

那么,还有比较好的,可以用于 react 环境下的 contextmenu 解决方案么?

谢谢!

如何在 Windows 10 平台的 make.exe 使用 powershell

Posted: 27 Jul 2021 12:20 AM PDT

从 macOS 迁移到 Windows 10 进行开发,在使用 make 的时候发现 make 貌似调用的是 cmd 而非 powershell,请问大家有没有遇到过类似的问题,以及最终如何解决。

make 版本

make --version GNU Make 4.3  Built for Windows32 

发现此问题时使用的 make 规则

clean: 	Remove-Item *.table 

H5 环境下的广告 SDK 有推荐吗?

Posted: 27 Jul 2021 12:18 AM PDT

有个游戏项目需要发布到网页端,看了一圈似乎大部分广告 SDK 都不支持 H5 直接接入,腾讯的优量汇支持 js,但也必须要先接入 QQ 登陆才行,还有其他推荐的 SDK 吗

手里有一块 itx 的 b360,于是咸鱼入手了一片 9900es

Posted: 27 Jul 2021 12:15 AM PDT

本来打算装 windows,没想到这张 9900es 有毛病,在 windows 下驱动似乎打不上去,核显只有 480p 。 manjaro 下倒是一切正常,intel 核显驱动打上了,GVT-g 到虚拟机没毛病,连 DX12 都正常,这可真是奇了个葩了。

日志收集系统 Fluentd & td-agent 内存占用逐渐增长是什么原因呢?

Posted: 27 Jul 2021 12:13 AM PDT

  • 1 、有多台机器,用同一镜像装的系统,负载均衡的同一个项目,只有最近新建的几台机器会有这种情况。
  • 2 、查看 td-agent 日志,大多时间并没有报错。版本是 fluentd (0.12.40),偶尔报错:
buffer flush took longer time than slow_flush_log_threshold: plugin_id="object:3fc788a54800" elapsed_time=21.867602169 slow_flush_log_threshold=20.0 
  • 3 、下图是 TOP 命令,ruby 程序占用内存会逐渐增长,直至服务器内存打满。 img
  • 4 、下面是 td-agent 状态 img 5 、下面是配置文件:
<source>     type forward     port 24224     bind 0.0.0.0 </source> ###加了下面这个 match 后,才出现内存增长的情况,但所有服务器都加了,只有最近建的机器才会出现 <match php.try.master.data.*.*>     type forward     send_timeout 10s     recover_wait 10s     heartbeat_interval 1s     phi_threshold 16     hard_timeout 60s     buffer_type memory     buffer_chunk_limit 8m     buffer_queue_limit 512     flush_interval 1s     <server>         name data-log         host 10.10.173.37         port 24224         weight 60     </server> </match>  <match php.**>     type forward     send_timeout 10s     recover_wait 10s     heartbeat_interval 1s     phi_threshold 16     hard_timeout 60s     buffer_type memory     buffer_chunk_limit 8m     buffer_queue_limit 64     flush_interval 2s     <server>         name php         host 10.10.12.49         port 24224         weight 60     </server> </match> 

新增了 match 之后, 最近新增的几台机器,内存偶尔会一直增长(一般出现在项目部署后),其他几台老机器没有任何问题。

是配置文件有问题吗?

求教各位彦祖,点赞系统设计的最佳实践?

Posted: 27 Jul 2021 12:07 AM PDT

我们有一个类知乎的服务,日活 500 万左右;用户可以对文章进行点赞,但是用户只有在文章详情页才可以进行点赞相关的查询和操作,QPS 也不高,所以直接走数据库查询也没有太大性能问题。 最近产品提出将点赞按钮前置到文章列表中的需求,我们每次分页会查询 50 篇文章的信息,肯定不能直接走数据库了。 目前我初步想法是将用户点赞数据放到 Redis 位图中,考虑到用户点赞其实是个相对低频的操作,点赞、取消点赞都直接操作 Redis,异步刷新到 DB,这样牺牲了部分可靠性,比如 Redis 挂了导致用户操作没有同步到 DB 、或者 Redis 操作成功,但是 DB 操作失败如何处理,还要考虑如异步调用乱序如何处理。 所以想请教下各位 V2er,这类点赞系统的设计有没有一些最佳实践?比如走 ES 或 Mongo?

Apereo CAS 服务的用户注册功能是要自己实现吗?

Posted: 26 Jul 2021 11:55 PM PDT

最近在调研 SSO 开源服务,最后在 Keycloak 和 CAS 中犹豫,功能看起来不分伯仲,但是跟着文档上手起来明显 CAS 比较吃力。

比如就用户注册功能,CAS 的文档完全没有提及,也没有找到如何接入,在 CAS 中这块是都要自己来实现的吗?

remax 用的人多吗?

Posted: 26 Jul 2021 11:53 PM PDT

前端路由可以和后端路由一起组合使用吗?

Posted: 26 Jul 2021 11:10 PM PDT

前端路由挺有意思的一个东西,url 的路由直接在浏览器完成拦截跳转,都绕过后端服务器了。

所以对前端路由这个机制还是不大理解,比如在浏览器地址栏直接输入一个 url 地址,也会被前端拦截掉吗?

那后端比如 nginx 设置的路由规则还有效吗?

GitHub 收录到自己 starts 里面有没有跟浏览器书签一样建一个文件夹,不然好难找呀?

Posted: 26 Jul 2021 04:32 PM PDT

我感觉懂点技术皮毛产品经理好可怕,让我觉得很难跟他合作

Posted: 26 Jul 2021 04:12 PM PDT

这是以前工作过的一家公司的产品经理,他属于懂点技术皮毛的那种,他很多时候就是想当然,总是认为这个功能做起来很简单。举个例子,当时要统计一个东西,我当时跟他说,这个做起来很复杂,涉及了好几个微服务,还设计到了一些业务,然后他就说,这个做起来不是很简单吗,数据库 group by 一下就好了呀(但他根本不知道我们后端是怎么划分的,怎么分库的,他只是凭着他知道的一点数据库知识来判断)……类似的例子数不胜数。后来……我就辞职了。

求一个 React Router 路由守卫的现成轮子

Posted: 26 Jul 2021 03:15 PM PDT

第一次写 React,官方的路由没有封装守卫

由于路由这块我还不是很熟悉,求一个现成的轮子.

彦祖们,这种 API 接口设计有哪些利弊?

Posted: 26 Jul 2021 07:08 AM PDT

最近在复刻一些产品做练手,发现了不少新产品的 web api 接口很有意思。两个典型参考对象是 wolai.comtodoist.com

传统上,我们会根据业务需求给不同的业务设计开发出不同的 api 接口出来给前端调用。

比如某个系统叫 V2EX,包含了对帖子的增删改查,我们往往会创建

/article/create
/article/update
/article/delete
/article/get/:id
/article/list/get

等接口。

然后处理分类还有
/category/create
/category/update
等等。

当然其中还有一些可以合并的,具体不一而足,因人而异。

但我最近看到了这样一些接口。使用方法类似于

/article

然后 payload 为

{ 	"resource_type": "article",         "transaction": [{     	"requestId": "some kind of uuid"     	"command":"updateArticle",         "args": {         	"articleId": some int or uuid,             "content": "some string",             "blahblah": "blahblah"         }     }] } 

这个 payload 本身不难看懂,其中 transaction 是个数组,可以一次包含多个指令。

这个让我想起来以前我们有的时候开的玩笑,说根本不需要写很多接口,只要一个接口,传不同的参就可以干所有的事。现在看来这个玩笑不仅被人真的这么做了,还给了很完善的事务概念。

但我仍然有些困惑,这样的模式真的很好用吗?

我能想到一些优势,比如前面可以是一个很薄的 controller, 后面随着 args 的不同调用不同的 service 处理。service 可以很轻松的切换版本,不需要担心和前端的对接。队列在后端的应用也是显而易见的。

对前端来说,也不再需要看 N 个接口的文档,大多数接口会统一起来有一套标准,只要定义约定好相关的行为和参数就可以。

但这样的接口调用,是不是本身就太复杂了呢? 我大概想了下,似乎没有看到很明显的收益。我大概看了下相关的前端,有这样一个特性。

比如说列表页,我新增一个内容,传统模式是先 create,然后再获取 list,进行 data 更新。 现在会改成先操作本地 data,直接在 list 里 append,然后再发一个事务描述,告诉后端去做对应的相关操作。

我甚至在某个 app 中遇到过事务失败的问题,然后造成了多端登录的情况下有一个端死活同步不了( Todoist,事务 ID 对不上,死活不能同步数据。)

就想问问各位大佬,这种接口设计除了我自己臆想分析的特征,还有什么别的是我没考虑到的吗?

No comments:

Post a Comment