Monday, August 23, 2021

V2EX - 技术

V2EX - 技术


鉴于 github 在国内的网络情况,你们会选择哪个代码托管平台作为替换, gitee、coding 还是 bitbucket?

Posted: 23 Aug 2021 04:33 AM PDT

github 在国内网络越来越不友好了,有时候 push 代码得尝试两三次才能成功,这种情况下,我考虑换一个平台作为第二选择。

有没有人觉得 Python Flask 写后端很难用?

Posted: 23 Aug 2021 04:15 AM PDT

  • 自我感觉 python 越用越难用,动态类型提示极其的不友好
  • flask 集成 sqlalchemy 想要返回 JSON 返回内容还需要通过 marshmallow 等把 python 对象转换
  • 如果想要使用登录管理集成 flask_login 等
  • 这样就会出现项目中存在多个模型定义文件
  • 再说 sqlalchemy 本身就挺复杂,然后类型提示大部分都没用,想不起来时候只能查文档,非常繁琐
  • 还有 flaks 本身导入通过一个全局 app 控制,这样进行项目分块时候极其不友好,有蓝图也一样,对比 dotnent 和 java 自识别,flask 需要手动注册就很麻烦了
  • 然后我总结一句就是,动态语言一时爽,过一段时间自己都不知道这个变量会产生什么结果类型

同一 NAS 不同硬盘间复制移动文件必须要走网络通信?

Posted: 23 Aug 2021 04:14 AM PDT

目前我的 NAS 里有多块硬盘没有组 RAID,系统是 OMV,通过 Samba 共享给主电脑

现在有个问题是我想在 NAS 的不同硬盘间复制或移动文件,但只要是通过 samba 管理,数据都是要经过我的电脑中转的,无法直接在 NAS 内部通过硬盘传送

而我网络目前只有千兆,数据通过电脑中转的话下载上传各占满带宽一半,导致移动文件的速度只有 50MB/s 左右非常慢。想问下只要是 samba 的话,这个问题就无解吗?

如果想要解决的话,有什么办法?只能在 NAS 里安装文件管理的 webui 之类的,在 webui 里移动复制文件?但通过 webui 的话还是比不上资源管理器管理文件方便好用。

有做过银行收款系统对接的业务吗?问了 5 家银行,都被客服小妹拒绝了

Posted: 23 Aug 2021 04:10 AM PDT

  • 背景:公司的客户每月要按时缴纳服务费,否则会有一系列暂停服务的措施(例如:关闭服务器等),支付后会延期或复通。

  • 情况:由于是公对公转账,不能接入如微信支付或支付宝这类能有支付回调的第三方支付平台。特意去搜索了几大行,都有开放平台,但是却没有相关的接入或申请的入口,为此都致电了客服,不是客服小妹不懂直接说没有,就是分配到分行或支行网点的工作人员跟进,他们只会跟你说有 APP 、短信足够你用了;再问深点,直接拒绝,说没有。


想请问有做过类似业务的大佬指点一下吗?


需求是:

客户转账后有到账推送(非短信、APP );如果没有服务端的推送,有明细的 API 也可以,系统拉下来后再对账就好了

大厂程序员的文档 PPT 能力非常重要

Posted: 23 Aug 2021 04:00 AM PDT

在福报厂干外包干了 1 年多,偶尔没事翻了翻语雀上面的各种文档,不禁感叹这些 p7,p8 大佬的文档能力,尤其是里面的各种思维导图、架构图,甚至 PPT,写的真好。

即使是一个普普通通的功能模块,没有涉及什么特别复杂的技术,但是只要那个架构图一画,各种颜色的模块,箭头指来指去,虽然看不懂,但是感觉很高大上的样子,很牛逼。

如果没有图,看起来就索然无味,平淡无奇,即使写的文字再多。

大佬们的述职报告更是无比奢华,看完之后再看看我以前写的,那就是小学作文。终于知道为什么大佬经常让我做一些白屏化的功能,原来是为了放在 PPT 里面给领导看的。

Python3 写异步 IO 方便吗?跟 NodeJS 比,有哪些不足之处。

Posted: 23 Aug 2021 03:37 AM PDT

最近了解了下 Python3 的 async/await 用起来跟 NodeJS 的差不多,找到的异步 Redis 和 Mongodb 库都还不错。

发现 requests 没有异步,想找个替代的,aiohttp 的语法太奇怪了,如下,得先创建一个 session,然后 xxx,写起来很是麻烦,特别是要把以前的同步代码改为异步的,突然想要放弃。

import aiohttp import asyncio  async def main():     async with aiohttp.ClientSession() as session:         pokemon_url = 'https://pokeapi.co/api/v2/pokemon/151'         async with session.get(pokemon_url) as resp:             pokemon = await resp.json()             print(pokemon['name'])  asyncio.run(main()) 

NodeJS 的 Promise 就非常爽,没有异步的自己包装下就好了,像 sleep 。

用 golang 写了一个字节数据的编解码, 可以简化编写 tcp 服务时, 消息的封装和解析

Posted: 23 Aug 2021 03:19 AM PDT

https://github.com/lai323/bytecodec

这个库实现 []bytestruct 编解码, 对于要处理特别多结构不同的字节消息

使用这个就不用每种消息类型都去写编解码了

可以向处理 json 一样处理字节数据

package main  import ( 	"fmt" 	"time"  	"github.com/lai323/bytecodec" )  type Header struct { 	SerialNo uint16 	Time     int64 }  type Packet struct { 	Header    Header 	Phone     string `bytecodec:"length:11"`      // 使用长度固定为 11 的字符串 	MsgLength uint8  `bytecodec:"lengthref:Msg"`  // 表示这个字段的值是 Msg 的字节长度 	Msg       string `bytecodec:"gbk"`            // 使用 GBK 编码 }   func main() { 	p := Packet{ 		Header: Header{ 			SerialNo: 1, 			Time:     time.Now().Unix(), 		}, 		Phone: "18102169375", 		Msg:   "你好", 	}  	b, err := bytecodec.Marshal(p) 	fmt.Println(fmt.Sprintf("%#v", b), err)  	out := &Packet{} 	err = bytecodec.Unmarshal(b, out) 	fmt.Println(fmt.Sprintf("%#v", out), err) }  

请推荐几个类似 Joplin 的个人笔记软件,要选一个终身使用

Posted: 23 Aug 2021 02:51 AM PDT

看中 joplin 以下几点:

1,开源

2,能加密

3,电脑手机等主流系统都有

4,单机使用和网络备份都 OK

这次选定之后我就要把 wiznot 和 notion 里的内容全部转过去了,以后也不想再换了,所以想再看看还有没有类似 joplin 的、做的更好的,要是没多久又换平台那真是折腾

私有云技术栈

Posted: 23 Aug 2021 02:49 AM PDT

一直想了解私有云,请问会用到哪些技术呢?请彦祖们指教

不用数据库, PHP 每 10 分钟内生成一个恒定随机数,该怎样实现?

Posted: 23 Aug 2021 02:42 AM PDT

api 请求一个 php 单文件,该 php 单文件(不调用数据库)每 10 分钟生成一个定值随机数,比如:

8:00~8:10 请求该 php,只输出定值 23

8:10~8:20 请求该 php,只输出定值 189

8:20~8:30 请求该 php,只输出定值 3

8:30~8:40 请求该 php,只输出定值 67

......

这个该怎样实现?

网站登陆可以使用 1password, bitwarden,那其他的密码呢,比如 ssh, mysql?

Posted: 23 Aug 2021 02:33 AM PDT

有没有可以给运维人员使用的密码管理软件,

可以存储数据库,SSH 或 AK/SK 等密钥。

Linux 运维,真的很累吗?

Posted: 23 Aug 2021 02:29 AM PDT

升级禅道版本的时候数据迁移出现了问题,本想去禅道官网找解决方案,翻到一篇帖子 https://www.zentao.net/redirect-index-19463.html

比较好奇,除了说到的 Nethogs 、IOZone 、IOTop 、IPtraf 等这些工具,还有哪些?

于是我又去百度了下,发现了这个帖子 https://cloud.tencent.com/developer/article/1115245,文章写的是 Linux 运维工程师必备的 80 个监控工具之第 30-80 个,于是,我又很认真的看了下这些工具,转给了我的朋友

这么多工具,就想到了 Linux 的命令,一看,又是 150 个: https://wenku.baidu.com/view/a3570adec281e53a5802ffcf.html,知乎一查,又是一大堆: https://www.zhihu.com/question/452895041/answer/1995175373

我朋友跟我说过,当运维其实很辛苦,这个活枯燥不出彩,救火的情况经常出现,导致他加班也多。

我的一上午,就这样过去了,升级问题没有解决,反而找了一大堆 Linux 运维相关的。难怪我经常要加班。

所以,Linux 运维真的累么?

安卓 9 一直卡在全盘加密 logo 是怎么回事

Posted: 23 Aug 2021 02:29 AM PDT

手贱点了全盘加密,提示过程中不能退出否则数据丢失,然后我干等了两点小时发现卡在界面无变化左上角还是开始加密的那刻,痛下决心强制重启发现可以正常开机,有遇到相同情况的吗?我的手机已 root 是不是跟着有关?

windows 改 hosts 时,网址开端是任意怎么去表示?

Posted: 23 Aug 2021 02:29 AM PDT

只要后面是 taobao.com 就去指定 ip
113.96.109.100 .taobao.com
113.96.109.100 *.taobao.com
试过以上 2 个方案都无效
有大神能解答吗?

我又来了开源视频了:《Mac 软件买多了比 Mac 都贵,这些免费软件可以帮你省一点》

Posted: 23 Aug 2021 01:54 AM PDT

WindMark 做的,加了点动画效果,自觉效果还行。

视频效果

图文版本

Mac 软件买多了比 Mac 都贵,这些免费软件可以帮你省一点

源文件和制作工具

Github: https://github.com/easychen/windmark-practice

有没有办法解决 U3D 里 Texture 的 GetPixel 和 SetPixel 的效率问题?

Posted: 23 Aug 2021 01:53 AM PDT

操作像素太慢了。

自建集群需要考虑的问题

Posted: 23 Aug 2021 01:29 AM PDT

  • 主节点是否高可用, 也就是主节点挂了一个,集群是不是还能正常工作,是不是还能更新部署应用, 应用在没有控制中心的情况下还能不能容错。

  • 工作节点池是否高可用,部分节点或整个可用区的节点跪了的情况,工作负载还能不能运行,能否通过自动添加新节点实现集群自愈,还是需要人工介入

  • 集群配置是否安全,内部组件通信是否使用和 TLS 加密和受信证书; 用户和应用是否是给予最小集群操作权限;容器默认安全策略是否设置正确; 节点是否访问了不必要的控制组件,对 etcd 的访问是否受控和是否进行认证

  • 集群内的服务是否安全, 如果公网能访问,是否有认证有授权。 集群 API 访问是否严格限制

  • 集群规划是否合理, 是否符合 CNCF 制定的标准

  • 集群节点是否由配置管理,而不是人肉管理的。 例如操作系统内核更新, 安全补丁,等行为是怎么实现的

  • 集群数据是否有恰当的备份, 备份是否包含所有的持久化存储, 是否有数据恢复方案,这些方案这多久测试一次

  • 对于运行中的集群是怎么维护的? 新节点是怎么加的? 已经有节点的配置变更是怎么做的? k8s 是怎么更新的, 有没有动态扩容, 怎么执行策略的(Enforce policies)

  • 整理自 https://www.oreilly.com/library/view/cloud-native-devops/9781492040750/

请教一下 ES 中的 rollover 问题

Posted: 23 Aug 2021 12:45 AM PDT

各位大佬们,我想问咨询一个 ES 中 Index Lifecycle Manage 中的 rollover 问题。

当前的情况:

我们为每一个客户每一天都创建一个 index,( index 的创建是通过定义的 template 自动创建的),

但是会存在有的客户某天或者某几天数据量特别大,使用一个 index 的话有些吃力,希望能够做到当某个 index

数据超过一定数量后 rollover 到一个新的 index 上。

我查了资料发现,实现 rollover 的话必须得创建一个写别名,在我的应用场景中,就是每个客户每天都要有个写别名,

好像没法通过模版为每天的 index 自动创建一个写别名,想问下各位大佬有没有什么好的解决方案。

如果调用的 api 只有同步的实现,调用方想使用类似异步的方案,是不是只能开线程

Posted: 23 Aug 2021 12:09 AM PDT

请教一些关于 JNA 的杂乱问题。。

Posted: 22 Aug 2021 11:15 PM PDT

一个调用第三方 so 库的程序,内存总是随着运行时间暴涨,dump 下来的 java heap 并不大,于是怀疑是 native heap 出现了内存泄漏。。

之后程序加上了定时 gc,情况只是稍微好转,native heap 的内存依旧持续增长。。。

请问下面哪些情况需要主动释放内存来避免 native heap 的内存泄漏呢?

//1 jna 回调 中的 pointer 或者结构体 public interface cb extends Callback {         public void invoke(LLong lAttachHandle, Pointer pstGrayInfo, Pointer dwUser); }  //pstGrayInfo 需要主动释放么?   //2 函数写入的出参结构体  boolean foo(Structure outparam);  //outparam 及其中包裹的结构体需要主动释放么?  //3 发现一些结构体中包含其他结构体,这个成员变量却不需要初始化就能正常使用  public static class A extends Structure { 		public B b; }  public static class B extends Structure{ 		public int a; }  这里 A 中的成员变量 b 不需要初始化,这个 b 需要手动释放么?  

有没有什么方法可以实时检测 mysql 数据库中某个值是否发生改变?

Posted: 22 Aug 2021 11:12 PM PDT

我现在是用一个 while 循环每隔一秒钟查询一次来判断的,有没有什么其他方法可以实现这个需求? 谢谢

网页版 bi 接口问题

Posted: 22 Aug 2021 10:59 PM PDT

用户在网页版 bi 上传数据或画图时,数据量大时接口可能会超时,有什么解决方案?像 power bi 和其他产品是怎么解决的?

mongodb 能否直接覆盖内嵌数组中的某条记录?

Posted: 22 Aug 2021 10:57 PM PDT

{
其他属性...,
"arrayname":[
{ "_id" : "abc", "totalSaleAmount" : NumberDecimal("170")....更多属性 },
{ "_id" : "xyz", "totalSaleAmount" : NumberDecimal("150")....更多属性 }
]
}

比如修改 _id:abc 这条数据,由于前端表单提交传来的是全量数据,一个字段一个字段的去 update 太麻烦了,而且要写复杂的过滤出 abc 这条记录的条件,所以我想直接覆盖 abc 这条记录,有没有 update 语句能直接覆盖整条 abc 记录?

我现在的写法是 spring 的 mongotemplate 先 pull,再 push,这样就产生了两次与 mongo 的交互。

我知道把内嵌数组拆出来就不用写复杂的过滤条件了,但是相对于整个文档的查询来说,内嵌数组的更新相对频率较低

windows10 家庭版,打开设置-Windows 预览计划,一片空白

Posted: 22 Aug 2021 08:32 PM PDT

如题~ 怎么解决?

[Vue、React 和 Angular 一起学]二三周总结

Posted: 22 Aug 2021 08:31 PM PDT

挑战活动 还在继续,但近两周一直在忙做饭,时间和精力都不太够用。

这两周主要在看组件的模板和样式。已写好的文档整理成了表格,对比着看很有意思。

https://github.com/LearnShare/learn-VRA#学习主题

欢迎交流和讨论:

  • learnshare.hjq#gmail
  • 各项目 issues

腾讯云轻量服务器安装历史上的今天网页及接口

Posted: 22 Aug 2021 08:20 PM PDT

0x01 应用简介 可以让你更方便了解历史上的今天发生了什么。早知天下大事情。 0x02 服务器准备 服务器的选择上,当然是本文的主角:腾讯云轻量应用服务器( Lighthouse )。这是目前最快的建站方式,我们开始上路吧~ 目前腾讯云最流行的 IaaS 层产品莫过于 Lighthouse (轻量应用服务器)了。该产品以套餐形式提供了便捷的云主机选购,网络流量包、应用镜像以及免密登录等特性也更加注重了人性化的体验。Lighthouse 作为目前最炙手可热的面向个人开发者及中小企业的新一代云服务产品,特别适合搭建个人博客、网站、论坛、小型应用等多种场景。另外,其良心的价格和促销力度也是前所未有,其持续运营的策略是相对面向未来的。 境外服务器价格及配置: image 14.png 国内服务器价格和配置: image 1.png 0x03 开始安装 1,打开域名控制台解析域名到服务器公网 ip image 3.png 2,打开轻量服务器控制台 重置应用选择宝塔专版 image 4.png 3,在面板中找到登录地址,账号及密码 4,登录宝塔安装以下应用 image 5.png 5,下载 history 源码 https://github.com/PrintNow/TodayInHistory 6,添加域名 image 6.png 7,进入根目录上传源码并进行解压 image 7.png 8,创建数据库并导入 image 8.png 9,配置网站 打开 api.php 配置数据库信息 打开 static/script.jc 编辑 image 9.png 将打码处改成你的域名或 ip image 10.png 10,api 接口 请求 image 11.png 返回数据 image 12.png 0x04 应用展示 image 13.png 部分截图

想自学一下 Web 开发,求推荐学习网站或者视频课程

Posted: 22 Aug 2021 08:14 PM PDT

有一点点的 c 语言、python 、linux 基础,都是极其入门的水平

获取 Git 中特定 commit-ish 全部 parents 的方法

Posted: 22 Aug 2021 08:08 PM PDT

效率最高的方式

git rev-parse <commit-ish>^@,parent 会显示在不同的行中,不论是查看还是解析,都会很容易。而且这是个底层命令,效率会很高。

要注意的是不要使用<commit-ish>^,这只会显示首个 parent,而不是 parents 。

其他方式盘点

下面的--pretty=%P更换为--pretty=raw也可以,后者会显示更多内容。

  1. git cat-file -p <commit-ish>^{}
  2. git show -p <commit-ish>^{} --pretty=%P --no-patch
  3. git log --pretty=%P -n 1 <commit-ish>
  4. git rev-list --parents -n 1 <commit-ish>

k8s 学习交流

Posted: 22 Aug 2021 07:50 PM PDT

学习学习 k8s 也有一段时间了,学习中遇到一些坑,虽说一般问题 google 都能解决,但是感觉还是孤军奋战不给力,想找对 k8s 感兴趣的小伙伴,一起学习交流。

欢迎在学习 k8s 或者对 k8s 感兴趣的、或者 k8s 大佬们,加微信学习交流: d2V3aW4xNjA3

WSL2 莫名其妙连不上网了

Posted: 22 Aug 2021 06:34 PM PDT

Host 主机网络

IPv4 地址 . . . . . . . . . . . . : 192.168.2.147 子网掩码  . . . . . . . . . . . . : 255.255.255.0 默认网关. . . . . . . . . . . . . : 192.168.2.2 

vEthernet(WSL)

连接特定的 DNS 后缀 . . . . . . . : IPv4 地址 . . . . . . . . . . . . : 172.28.16.1 子网掩码  . . . . . . . . . . . . : 255.255.240.0 默认网关. . . . . . . . . . . . . : 

WSL2 Ubuntu ip addr

eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether 00:15:5d:20:c4:7d brd ff:ff:ff:ff:ff:ff inet 172.28.18.225/20 brd 172.28.31.255 scope global eth0    valid_lft forever preferred_lft forever inet6 fe80::215:5dff:fe20:c47d/64 scope link    valid_lft forever preferred_lft forever     

状况

  • 1 、一开始是间歇性无法联网,无法连接外网,表现为 apt-get update 时请求失败,国内源
  • 2 、尝试 ping www.baidu.com等外网域名,超时,nslookup能够正常解析域名 IP,在 host 主机上也能够正常 ping 通域名
  • 3 、尝试 ping 192.168.2.147 host 主机及局域网 ip 地址,会出现在第一条 ping 响应消息之后就卡住不动了,也出现过卡在第三次之后不动
  • 4 、ping 172.28.16.1 vEthernet(WSL)网关正常
  • 5 、尝试了 host 主机上重置各种网络设置 netsh winsock reset,然后重启 WSL,无效

不知道有没有遇到和我一样问题的朋友,现在没有头绪应该怎么处理这个问题了,google 了一圈,好像没有类似的情况,虽然是 Windows 的子系统,还是发在 Linux 节点吧,麻烦大佬指教

用 Go 轻松完成一个 TCC 分布式事务,保姆级教程

Posted: 22 Aug 2021 06:13 PM PDT

什么是 TCC,TCC 是 Try 、Confirm 、Cancel 三个词语的缩写,最早是由 Pat Helland 于 2007 年发表的一篇名为《 Life beyond Distributed Transactions:an Apostate's Opinion 》的论文提出。

TCC 组成

TCC 分为 3 个阶段

  • Try 阶段:尝试执行,完成所有业务检查(一致性), 预留必须业务资源(准隔离性)
  • Confirm 阶段:如果所有分支的 Try 都成功了,则走到 Confirm 阶段。Confirm 真正执行业务,不作任何业务检查,只使用 Try 阶段预留的业务资源
  • Cancel 阶段:如果所有分支的 Try 有一个失败了,则走到 Cancel 阶段。Cancel 释放 Try 阶段预留的业务资源。

TCC 分布式事务里,有 3 个角色,与经典的 XA 分布式事务一样:

  • AP/应用程序,发起全局事务,定义全局事务包含哪些事务分支
  • RM/资源管理器,负责分支事务各项资源的管理
  • TM/事务管理器,负责协调全局事务的正确执行,包括 Confirm,Cancel 的执行,并处理网络异常

如果我们要进行一个类似于银行跨行转账的业务,转出( TransOut )和转入( TransIn )分别在不同的微服务里,一个成功完成的 TCC 事务典型的时序图如下: image.png

TCC 网络异常

TCC 在整个全局事务的过程中,可能发生各类网络异常情况,典型的是空回滚、幂等、悬挂,由于 TCC 的异常情况,和 SAGA 、可靠消息等事务模式有相近的地方,因此我们把所有异常的解决方案统统放在这篇文章《还被分布式事务的网络异常困扰吗?一个函数调用帮你搞定它》进行讲解

TCC 实践

对于前面的跨行转账操作,最简单的做法是,在 Try 阶段调整余额,在 Cancel 阶段反向调整余额,Confirm 阶段则空操作。这么做带来的问题是,如果 A 扣款成功,金额转入 B 失败,最后回滚,把 A 的余额调整为初始值。在这个过程中如果 A 发现自己的余额被扣减了,但是收款方 B 迟迟没有收到余额,那么会对 A 造成困扰。

更好的做法是,Try 阶段冻结 A 转账的金额,Confirm 进行实际的扣款,Cancel 进行资金解冻,这样用户在任何一个阶段,看到的数据都是清晰明了的。

下面我们进行一个 TCC 事务的具体开发

目前可用于 TCC 的开源框架,主要为 Java 语言,其中以 seata 为代表。我们的例子采用 go 语言,使用的分布式事务框架为https://github.com/yedf/dtm,它对分布式事务的支持非常优雅。下面来详细讲解 TCC 的组成

我们首先创建两张表,一张是用户余额表,一张是冻结资金表,建表语句如下:

CREATE TABLE dtm_busi.`user_account` (   `id` int(11) AUTO_INCREMENT PRIMARY KEY,   `user_id` int(11) not NULL UNIQUE ,   `balance` decimal(10,2) NOT NULL DEFAULT '0.00',   `create_time` datetime DEFAULT now(),   `update_time` datetime DEFAULT now() );  CREATE TABLE dtm_busi.`user_account_trading` (   `id` int(11) AUTO_INCREMENT PRIMARY KEY,   `user_id` int(11) not NULL UNIQUE ,   `trading_balance` decimal(10,2) NOT NULL DEFAULT '0.00',   `create_time` datetime DEFAULT now(),   `update_time` datetime DEFAULT now() ); 

trading 表中,trading_balance 记录正在交易的金额。

我们先编写核心代码,冻结 /解冻资金操作,会检查约束 balance+trading_balance >= 0,如果约束不成立,执行失败

func adjustTrading(uid int, amount int) (interface{}, error) {   幂等、悬挂处理   dbr := sdb.Exec("update dtm_busi.user_account_trading t join dtm_busi.user_account a on t.user_id=a.user_id and t.user_id=? set t.trading_balance=t.trading_balance + ? where a.balance + t.trading_balance + ? >= 0", uid, amount, amount)   if dbr.Error == nil && dbr.RowsAffected == 0 { // 如果余额不足,返回错误     return nil, fmt.Errorf("update error, balance not enough")   }   其他情况检查及处理 } 

然后是调整余额

func adjustBalance(uid int, amount int) (ret interface{}, rerr error) {   幂等、悬挂处理   这里略去进行相关的事务处理,包括开启事务,以及在 defer 中处理提交或回滚   // 将原先冻结的资金记录解冻   dbr := db.Exec("update dtm_busi.user_account_trading t join dtm_busi.user_account a on t.user_id=a.user_id and t.user_id=? set t.trading_balance=t.trading_balance + ?", uid, -amount)   if dbr.Error == nil && dbr.RowsAffected == 1 { // 解冻成功     // 调整金额     dbr = db.Exec("update dtm_busi.user_account set balance=balance+? where user_id=?", amount, uid)   }   其他情况检查及处理 } 

下面我们来编写具体的 Try/Confirm/Cancel 的处理函数

RegisterPost(app, "/api/TransInTry", func (c *gin.Context) (interface{}, error) {   return adjustTrading(1, reqFrom(c).Amount) }) RegisterPost(app, "/api/TransInConfirm", func TransInConfirm(c *gin.Context) (interface{}, error) {   return adjustBalance(1, reqFrom(c).Amount) }) RegisterPost(app, "/api/TransInCancel", func TransInCancel(c *gin.Context) (interface{}, error) {   return adjustTrading(1, -reqFrom(c).Amount) })  RegisterPost(app, "/api/TransOutTry", func TransOutTry(c *gin.Context) (interface{}, error) {   return adjustTrading(2, -reqFrom(c).Amount) }) RegisterPost(app, "/api/TransOutConfirm", func TransInConfirm(c *gin.Context) (interface{}, error) {   return adjustBalance(2, -reqFrom(c).Amount) }) RegisterPost(app, "/api/TransOutCancel", func TransInCancel(c *gin.Context) (interface{}, error) {   return adjustTrading(2, reqFrom(c).Amount) })  

到此各个子事务的处理函数已经 OK 了,然后是开启 TCC 事务,进行分支调用

// TccGlobalTransaction 会开启一个全局事务 _, err := dtmcli.TccGlobalTransaction(DtmServer, func(tcc *dtmcli.Tcc) (rerr error) {   // CallBranch 会将事务分支的 Confirm/Cancel 注册到全局事务上,然后直接调用 Try   res1, rerr := tcc.CallBranch(&TransReq{Amount: 30}, host+"/api/TransOutTry", host+"/api/TransOutConfirm", host+"/api/TransOutRevert"   进行错误检查,以及其他逻辑   res2, rerr := tcc.CallBranch(&TransReq{Amount: 30}, host+"/api/TransInTry", host+"/api/TransInConfirm", host+"/api/TransInRevert")   进行错误检查,有任何错误,返回错误,回滚交易   // 如果没有错误,函数正常返回后,全局事务会提交,TM 会调用各个事务分支的 Confirm,完成整个事务 }) 

至此,一个完整的 TCC 分布式事务编写完成。

如果您想要完整运行一个成功的示例,那么按照 dtm 项目的说明搭建好环境之后,运行下面命令运行 tcc 的例子即可

go run app/main.go tcc_barrier

TCC 的回滚

假如银行将金额准备转入用户 2 时,发现用户 2 的账户异常,返回失败,会怎么样?我们修改代码,模拟这种情况:

RegisterPost(app, "/api/TransInTry", func (c *gin.Context) (interface{}, error) {   return gin.H{"dtm_result":"FAILURE"}, nil }) 

这是事务失败交互的时序图 image.png

这个跟成功的 TCC 差别就在于,当某个子事务返回失败后,后续就回滚全局事务,调用各个子事务的 Cancel 操作,保证全局事务全部回滚。

小结

在这篇文章里,我们介绍了 TCC 的理论知识,也通过一个例子,完整给出了编写一个 TCC 事务的过程,涵盖了正常成功完成,以及成功回滚的情况。相信读者通过这边文章,对 TCC 已经有了深入的理解。

关于分布式事务中需要处理的幂等、悬挂、空补偿,请参考另一篇文章:分布式事务你不能不知的坑,一个函数调用帮你搞定它

关于分布式事务更多更全面的知识,请参考分布式事务最经典的七种解决方案

文中使用的例子节选自yedf/dtm,支持多种事务模式:TCC 、SAGA 、XA 、事务消息 跨语言支持,已支持 golang 、python 、PHP 、nodejs 等语言的客户端。提供子事务屏障功能,优雅解决幂等、悬挂、空补偿等问题。 ​ 阅读完此篇干货,欢迎大家访问https://github.com/yedf/dtm项目,给颗星星支持!

The Linux Kernel Module Programming Guide 升级至 5.0 版并开源!

Posted: 22 Aug 2021 04:21 PM PDT

台湾成功大学助理教授 黄敬群 (Jim Huang, jserv) 近期将 The Linux Kernel Module Programming Guide (Linux 内核模块编程指南) (针对 Linux Kernel 2.6) 的内容升级到最新的 kernel versions (v5.x)。

并且大方的开源 LaTeX 、PDF 至 GitHub 上,欢迎对 Linux 内核感兴趣的伙伴们,可以阅读学习。

GitHub 项目连结

各位老哥,快奔三了,我也来聊聊要不要回老家的事

Posted: 22 Aug 2021 01:00 PM PDT

  • 背景如下:*

楼主今年已经二十八九岁了。这几年存款全都贡献给老家的房子了(大城市实在有点 hold 不住,没法强行上)。

现在报考了一家单位的合同工(没编),笔试过了,面试还没开始

打听了下收入差不多刚刚好税后刚刚好 10w,五险一金也是按低额度交的(因为合同工)。

目前工作了五六年,现在刚刚税前 20k 出头。因为老家的房子也掏干了我,所以在大城市买房应该最近这三五年是希望渺茫。所以有点回老家的想法了。不知道各位老哥们怎么看。


我也听人说过你回去了,你的后代还是会面临你同样的悲剧,其实我也有点明白,但是随着年龄的增长,我也渐渐接受了平庸的自己。每个人家庭背景,生长环境都不一样,其实只要自己活的明白就行。

其实我自己因为也没经历过回老家这种收入突然降低那么多的落差,就怕自己有点接受不了,内心是有点想回去的,所以很纠结,虽然现在面试还得过一两周才开始,其实我过的概率还是挺大的,因为我的岗位就是给单位做做点小开发,我还是有点优势的,毕竟虽然没去过一线大厂,但是毕竟在三线或者说是 2.5 线的公司勤恳的干过- -

把 Java 写成动态语言了,越改越崩溃。

Posted: 22 Aug 2021 07:09 AM PDT

各种 map,前台数据传到后台转换成 map 或者 list<Map>,数据库查询返回 list<Map>,方法调用传参数也是 Map,现在改个东西,完全不知道会影响到哪里,因为都是 Map 参数,方法签名一般都不变,但是 Map 里面的数据不仔细看根本不读知道都有什么,真是越改越崩溃。
另外 map 取数也是各种类型转换,各种 null 判断。
及其 ugly 的代码。

No comments:

Post a Comment