Saturday, November 20, 2021

V2EX - 技术

V2EX - 技术


手机应用的后端与网页的后端开发有什么区别?

Posted: 20 Nov 2021 10:47 PM PST

比如需求或设计上是否有不同?如果有兴趣,也可以聊聊共性。

关于 asyncio 执行 IO 密集型操作的不解

Posted: 20 Nov 2021 10:26 PM PST

有一个读文件然后写数据库的操作,想尝试使用协程。
使用协程的:

async def parse_text(file_path: Path, context_qs: [asyncio.Queue]):     ql = len(context_qs)     i = 0     # 每一个 Queue 放 step 个数据就切换下一个     step = 2     with open(file_path, encoding="utf8") as f:         for text in f:             if i // step == ql:                 i = 0             context_q = context_qs[i // step]             context = {}             text = re.findall(r"\d+", text)             if text:                 context = {"解析然后组装成 dict"}                 await context_q.put(context)                 # 这里如果不 join ,会一直在这个 for 循环里不出去                 await context_q.join()                 i = i + 1         else:             await context_q.put("结束标记")             return   async def write_db(context_q: asyncio.Queue, model: ModelBase):     async with AsyncSession() as session:         while 1:             context = await context_q.get()             if context["结束标记"] == "end":                 return             info, obj = None, None             try:                 if context["info"]:                     info = await session.execute(                         select(InfoModel).filter(                             InfoModel.attr == context["info"]                         )                     )                     info = info.scalars().one_or_none()                     if not info:                         info = InfoModel(attr=context["info"])                         session.add(info)                 if context["header"]:                     obj = await session.execute(                         select(model).filter(                             model.header == context["header"]                         ).options(selectinload(getattr(model, "info")))                     )                     obj = obj.scalars().one_or_none()                     if not obj:                         obj = model(header=context["header"])                         session.add(obj)                 if obj or info:                     if info not in obj.info:                         obj.info.append(info)                         session.add(obj)                     await session.commit()             except Exception as e:                 await session.rollback()                 raise e             else:                 context_q.task_done()   async def main(): 	# 每个读取文件并解析的方法对应 c_q_count 个写数据库的方法     c_q_count = 3     a_context_qs = [asyncio.Queue() for i in range(c_q_count)]     b_context_qs = [asyncio.Queue() for i in range(c_q_count)]     tasks = [         asyncio.create_task(             parse_text(Path("a.txt"), a_context_qs)         ),         asyncio.create_task(             parse_text(Path("b.txt"), b_context_qs)         ),     ]     for i in range(c_q_count):         tasks.append(asyncio.create_task(write_db(a_context_qs[i], AModel)))         tasks.append(asyncio.create_task(write_db(b_context_qs[i], BModel)))     await asyncio.gather(*tasks)    if __name__ == '__main__':     asyncio.run(main(), debug=settings.DEBUG)  

不使用协程的:

def sync_read_file():     af = Path("a.txt").open(encoding="utf8")     bf = Path("b.txt").open(encoding="utf8")     with Session() as session:         while 1:             if af:                 try:                     text = af.readline()                     context = parse_text(text)                     sync_write_db(session, context, AModel)                 except IOError:                     af.close()                     af = None             if bf:                 try:                     text = bf.readline()                     context = parse_text(text)                     sync_write_db(session, context, BModel)                 except IOError:                     bf.close()                     bf = None             if not af and not bf:                 return   def sync_write_db(session, context, model):     info, obj = None, None     try:         if context["info"]:             info = session.execute(                 select(Info).filter(                     Info.attr == context["info"]                 )             )             info = info.scalars().one_or_none()             if not info:                 info = Info(attr=context["info"])                 session.add(info)         if context["header"]:             obj = session.execute(                 select(model).filter(model.info == context["info"]))             obj = obj.scalars().one_or_none()             if not obj:                 obj = model(info=context["info"])                 session.add(obj)         if obj or info:             if info not in obj.info:                 obj.info.append(info)                 session.add(obj)             session.commit()     except Exception as e:         session.rollback()         raise e   if __name__ == '__main__':     sync_read_file()  

这个协程的方法,每秒每个表可以写 400 多行,改为同步单线程的还是每秒写 400 多行。
不知道是我协程的用法有问题?还是说有别的什么原因?

关于 RDAP 协议的一些疑问

Posted: 20 Nov 2021 10:17 PM PST

whois 协议是 43 端口的文本通信
新的 RDAP 基于 http 协议,然后我去 icann 上找相关注册局的 RDAP 地址,但是我找不到
有大佬知道吗
还有关于请求速率的问题
Queries that come from "trusted" sources are rate-limited at a maximum query rate of 7,200 queries per hour. Any queries in excess of this query rate will be refused until the query rate falls below this limit.
"Trusted" sources will not be permanently blocked. 是所有的注册局的 whois/RDAP 服务统一限制这个次数么?

这样加锁会导致什么问题?

Posted: 20 Nov 2021 09:59 PM PST

String lock = userId;
synchronized(lock.intern()){
}

userId 是唯一的。

这样加锁常量池的数据会很庞大,会被 GC 及时回收吗

google play 开发者账号,被暂缓付款有谁碰到过吗?

Posted: 20 Nov 2021 07:48 PM PST

刚注册,这个月应该有收益,但是突然显示暂停付款。然后点开就是联系我们
但是谷歌哪里有什么联系我们。
之前认证提交的材料都提交了。税,绑定银行。都有了不知道材料还遗漏了什么。
有谁碰到过吗。

有什么方法对违反 GPL 协议的国内大厂做出行动?

Posted: 20 Nov 2021 06:28 PM PST

如果,我只是说如果,有一个硬件厂商,假设它叫某米(不包含任何暗示),开发了一系列手机,系统是基于 Android 的魔改(仍然使用 Linux 内核),因为 GPL 许可证的原因在 GitHub 上发布了声称是手机内核的源代码。但是我有一个朋友在尝试自己编译内核的时候发现有一些官方 ROM (系统镜像)里预编译的内核的配置参数在开源的内核里根本不存在,也就是说很可能开源的内核和分发的编译后的二进制内核是不匹配的。

这样的行为应该是违反了 GNU 许可证的规范了(src)(src2),那么有什么方法可以制止这样的行为吗?如果我向gpl-violations.org提交相应的报告的话会有进展吗?国内有(除了开发者起诉之外)相应的案例吗?

如何理解双向循环神经网络?用在分类问题时是否无意义?

Posted: 20 Nov 2021 02:47 PM PST

如题,看了一些双向 rnn ( lstm )的文章,以我的理解,rnn 每层的最终 output 应该表示的是当前时刻(序列)的状态。那么在进行一些比如情感分析,或分类,等等对一个序列进行定性的问题时,双向 rnn 是否没有意义?因为其输出应该代表最后一个状态,正向 rnn 已经有了,反向 rnn 的话最后一个状态反过来说只是一个初始值?

APT 2.3.12 禁止交互式卸载必须的软件包

Posted: 20 Nov 2021 01:32 PM PST

新闻来源: https://www.gamingonlinux.com/2021/11/apt-2312-package-manager-released-will-no-longer-let-you-break-everything/

前情提要: https://www.bilibili.com/video/BV1Fh411b7q3

在 Pop!_OS 中安装 Steam 客户端会导致桌面环境被卸载(尚未解决的 bug )。虽然执行前会有警告并要求输入"Yes, do as I say"确认,但这根本不足以劝退不明白事情严重性的初级 Linux 用户。新版本将会拒绝执行且不会提示用户。

该修改已经并入 debian testing 。 说实话我也没理解什么情况需要支持卸载 essential 的软件包。

关于 OpenCV+CUDA 在 Win11 编译安装

Posted: 20 Nov 2021 11:27 AM PST

环境描述 CPU 5800x ,GPU 750Ti ,CUDA 11.5 ,Win11 ,OpenCV4.5.4 弄了好几天了,不太确定是不是 win11 的问题,编译是都通过了,但是 cv2 包导入不成功,确实对 win 没啥经验,不知道有没 CV 的大佬帮助一下小弟

Traceback (most recent call last):   File "<stdin>", line 1, in <module>   File "C:\Python\Python310\lib\site-packages\cv2\__init__.py", line 183, in <module>     bootstrap()   File "C:\Python\Python310\lib\site-packages\cv2\__init__.py", line 155, in bootstrap     native_module = importlib.import_module("cv2")   File "C:\Python\Python310\lib\importlib\__init__.py", line 126, in import_module     return _bootstrap._gcd_import(name[level:], package, level) ImportError: DLL load failed while importing cv2: 找不到指定的模块。 

K8S 跑宝塔

Posted: 20 Nov 2021 11:25 AM PST

帮朋友管理好几个网站,基本都是基于 wp,分散在好几个小鸡上,管理起来很烦。

在想能不能基于 K8S 跑个宝塔,这样扩容和管理起来比较方便, 有些项目测试也可以在 K8S 上跑, 哪位大佬搞过,分享下思路。

请教后端业务逻辑代码如何分离

Posted: 20 Nov 2021 09:27 AM PST

node+koa ,有这样一个接口:

router.post(   '/order',   {...},    async ctx => {     const { body } = ctx.request     // 一些需要查询数据库的参数验证逻辑,比如:     const item = await Item.findOne({ where: { id: body.id } })     if (!item) {       throw Error('item not existing')     }     // 后续逻辑     const result = await createOrder(body)     ctx.body = result.id   } ) 

createOrder这个函数因为其他接口 /逻辑也会用到所以单独抽出来了,于是产生个问题: 函数内部也有用到查询Item的地方,那这样的话,/order这一个接口得查询Item两次。例子是查一个,查列表的情况岂不是更浪费。

抽象出来大概是:如何避免 通用业务逻辑 与 调用它的 route 之间重复相同数据库查询操作?

求赐教!谢谢!

kubeadm 部署多 master 节点问题,高可用必须 2 台在线才行吗?

Posted: 20 Nov 2021 09:15 AM PST

折腾一天了,一共三台 master 节点机器 用 keepalived 做虚拟 ip ,开启了 lvsf ,测试关闭其中任意一台,另外两台都没问题,但是只要关闭 2 台,服务就不可用了.

  • 错误如下
[root@master-1 ~]# kubectl get nodes  The connection to the server 192.168.0.8:6443 was refused - did you specify the right host or port? [root@master-1 ~]# netstat -ntlp |grep 6443  

具体日志

  • kube-apiserver
[root@master-1 ~]# docker ps -a |grep kube-api|grep -v pause 0c1c0042b8c2   53224b502ea4                                        "kube-apiserver --ad…"   About a minute ago   Exited (1) 54 seconds ago                 k8s_kube-apiserver_kube-apiserver-master-1.host.com_kube-system_464df844856c9d5461cb184edc4974c9_45 [root@master-1 ~]# docker logs -f 0c1c0042b8c2 I1120 14:25:26.120729       1 server.go:553] external host was not specified, using 192.168.0.11 I1120 14:25:26.122152       1 server.go:161] Version: v1.22.3 I1120 14:25:26.836619       1 shared_informer.go:240] Waiting for caches to sync for node_authorizer I1120 14:25:26.838689       1 plugins.go:158] Loaded 12 mutating admission controller(s) successfully in the following order: NamespaceLifecycle,LimitRanger,ServiceAccount,NodeRestriction,TaintNodesByCondition,Priority,DefaultTolerationSeconds,DefaultStorageClass,StorageObjectInUseProtection,RuntimeClass,DefaultIngressClass,MutatingAdmissionWebhook. I1120 14:25:26.838721       1 plugins.go:161] Loaded 11 validating admission controller(s) successfully in the following order: LimitRanger,ServiceAccount,PodSecurity,Priority,PersistentVolumeClaimResize,RuntimeClass,CertificateApproval,CertificateSigning,CertificateSubjectRestriction,ValidatingAdmissionWebhook,ResourceQuota. I1120 14:25:26.840979       1 plugins.go:158] Loaded 12 mutating admission controller(s) successfully in the following order: NamespaceLifecycle,LimitRanger,ServiceAccount,NodeRestriction,TaintNodesByCondition,Priority,DefaultTolerationSeconds,DefaultStorageClass,StorageObjectInUseProtection,RuntimeClass,DefaultIngressClass,MutatingAdmissionWebhook. I1120 14:25:26.841003       1 plugins.go:161] Loaded 11 validating admission controller(s) successfully in the following order: LimitRanger,ServiceAccount,PodSecurity,Priority,PersistentVolumeClaimResize,RuntimeClass,CertificateApproval,CertificateSigning,CertificateSubjectRestriction,ValidatingAdmissionWebhook,ResourceQuota. Error: context deadline exceeded 
  • etcd 错误是 RAFT NO LEADER
[root@master-1 ~]# docker ps -a |grep etcd dfd6026ae3fd   004811815584                                        "etcd --advertise-cl…"   3 minutes ago    Up 3 minutes                          k8s_etcd_etcd-master-1.host.com_kube-system_a23c864b52d59788909994fe31a97f5e_8 13c6e65046d6   004811815584                                        "etcd --advertise-cl…"   7 minutes ago    Exited (2) 3 minutes ago              k8s_etcd_etcd-master-1.host.com_kube-system_a23c864b52d59788909994fe31a97f5e_7 5ca2f134f743   registry.aliyuncs.com/google_containers/pause:3.5   "/pause"                 22 minutes ago   Up 22 minutes                         k8s_POD_etcd-master-1.host.com_kube-system_a23c864b52d59788909994fe31a97f5e_1 [root@master-1 ~]# docker logs -n 10 13c6e65046d6 {"level":"warn","ts":"2021-11-20T14:24:39.911Z","caller":"rafthttp/probing_status.go:68","msg":"prober detected unhealthy status","round-tripper-name":"ROUND_TRIPPER_RAFT_MESSAGE","remote-peer-id":"ad7fc708963cf6f3","rtt":"0s","error":"dial tcp 192.168.0.9:2380: i/o timeout"} {"level":"warn","ts":"2021-11-20T14:24:39.915Z","caller":"rafthttp/probing_status.go:68","msg":"prober detected unhealthy status","round-tripper-name":"ROUND_TRIPPER_SNAPSHOT","remote-peer-id":"c68a49f4a0c3cea9","rtt":"0s","error":"dial tcp 192.168.0.10:2380: connect: no route to host"} {"level":"warn","ts":"2021-11-20T14:24:39.915Z","caller":"rafthttp/probing_status.go:68","msg":"prober detected unhealthy status","round-tripper-name":"ROUND_TRIPPER_RAFT_MESSAGE","remote-peer-id":"c68a49f4a0c3cea9","rtt":"0s","error":"dial tcp 192.168.0.10:2380: connect: no route to host"} {"level":"info","ts":"2021-11-20T14:24:40.658Z","logger":"raft","caller":"etcdserver/zap_raft.go:77","msg":"cb18584c4f4dbfc is starting a new election at term 7"} {"level":"info","ts":"2021-11-20T14:24:40.658Z","logger":"raft","caller":"etcdserver/zap_raft.go:77","msg":"cb18584c4f4dbfc became pre-candidate at term 7"} {"level":"info","ts":"2021-11-20T14:24:40.658Z","logger":"raft","caller":"etcdserver/zap_raft.go:77","msg":"cb18584c4f4dbfc received MsgPreVoteResp from cb18584c4f4dbfc at term 7"} {"level":"info","ts":"2021-11-20T14:24:40.658Z","logger":"raft","caller":"etcdserver/zap_raft.go:77","msg":"cb18584c4f4dbfc [logterm: 7, index: 3988] sent MsgPreVote request to ad7fc708963cf6f3 at term 7"} {"level":"info","ts":"2021-11-20T14:24:40.658Z","logger":"raft","caller":"etcdserver/zap_raft.go:77","msg":"cb18584c4f4dbfc [logterm: 7, index: 3988] sent MsgPreVote request to c68a49f4a0c3cea9 at term 7"} {"level":"warn","ts":"2021-11-20T14:24:41.729Z","caller":"etcdhttp/metrics.go:166","msg":"serving /health false; no leader"} {"level":"warn","ts":"2021-11-20T14:24:41.729Z","caller":"etcdhttp/metrics.go:78","msg":"/health error","output":"{\"health\":\"false\",\"reason\":\"RAFT NO LEADER\"}","status-code":503} 

结论

etcd 没有选出 leader 节点?单个 etcd 不能用吗?求大佬支招

electron 源码保护方案探讨。

Posted: 20 Nov 2021 08:47 AM PST

打包工具:electron-builder ,前端框架 vue ,使用了不少 3rd 的 node modules

目前需要能对 main proc 和 render proc 的 js 代码进行加密保护。
目前看到比较靠谱的方案是 bytenode ,有没有实践过的同学来给个最小例子?
或者还有没有侵入性较小更好的源码保护方案呢?

mysql 减库存并发问题

Posted: 20 Nov 2021 08:36 AM PST

减库存数量为 num

update mytable set inventory = inventory-num WHERE id= 1 and inventory >=num

这样减库存不用加乐观锁和悲观锁,也可以是吧

但是有什么弊端吗

ubuntu 如何将浏览器复制的内容快捷粘贴到 vim 编辑器里面呢?每次都要右键点击粘贴有点慢。。

Posted: 20 Nov 2021 06:17 AM PST

WSL 不能识别双通道内存是什么鬼?

Posted: 20 Nov 2021 05:17 AM PST

两个 16G 内存,win 上面能识别,WSL 只能识别 16G

申请 apple 开发者账号,发生了有意思的事情

Posted: 20 Nov 2021 04:40 AM PST

首先是用自己的 apple id ,一登录,和很多人一样,直接弹出"未知错误"。

网上一搜,非常普遍,我估计是 apple 内部的限制策略,就是故意禁止一些情况的 apple id 注册。

然后我注册了一个新的 apple id ,绑定的是老的手机号。

登录成功了,然后弹出一个协议,我点同意,没几秒,无任何提示直接弹出,像是把我踢下线了。。

当我再想登录的时候,就弹出"未知错误"了。。看来还得换个手机号才行。。。过两天再试试

有没有人摸索出能 100%通过的注册流程? 是不是要 新 iOS 设备 + 新 appleid + 新手机号,这样最保险?

有没有什么浏览器扩展,可以整合管理 chrome、edge、firefox 浏览器的收藏夹?由于工作原因,目前我用了三种浏览器,每个浏览器都有各自的收藏夹,不能同步管理,很是崩溃。

Posted: 20 Nov 2021 04:10 AM PST

如题,希望大佬帮忙推荐一下。我会不定时发送感谢。

谢谢大佬们了。

浏览器打印网页的时候, 图片在当前页放不下, 被挤到下面去了, 然后破坏了样式

Posted: 20 Nov 2021 03:16 AM PST

请问怎么样才能解决这个问题

Android 防定位造假的策略都有哪些呢??

Posted: 20 Nov 2021 01:18 AM PST

大佬们,很多定位作弊软件基本都是双开 /虚拟空间造假定位数据,,安卓有啥明确的特征值可以判定定位造假么,还是只能监测是否被 hook ,存在虚拟空间之类的。。。。

dubbo+zookeeper ,本地热部署后服务丢失的问题

Posted: 20 Nov 2021 12:14 AM PST

dubbo 服务注册到 zookeeper ,一开始启动后是正常可以访问的,但是 idea 里面只有要热更新操作,和 zookeeper 的连接就会断开,不会再注册进去,怎么解

springboot 单机 qps 只有 2000 合理吗?

Posted: 19 Nov 2021 11:47 PM PST

我们用的 springcloud 那一套,部署在阿里云的 ecs 上。

ecs 配置:4c 8g
程序流程:从 rds (mysql) 中获取数据,放入 redis ,然后做 vo 转换,返回。如果有 redis 有数据,就会直接返回,不会从 mysql 中获取。

目前结果是单机 qps 只能到 2000 ,超过 3000 之后,机器负载就会很高,比如 cpu 超过 70%, 内存也超过 70%。

我们高峰 qps 有 3w , 感觉只能加很多机器才能抗住。

我的问题是:springboot 的单机 qps 这么低吗?

iOS JS 零宽断言的正则问题

Posted: 19 Nov 2021 11:13 PM PST

互联网搜索了一波,发现这东西就是会触发异常,那么像前置零宽断言这种语句可以有什么办法改写吗?本人实在是正则苦手,或者求一波正则学习的方法。

异常的是

/(?<=[0-9])x\b/ 

需要匹配 25x 50x 中的 x

目前想到的办法是用

.replace /()()/, '$1 x' 

这种办法

Windows Ltsc 2021 来了

Posted: 19 Nov 2021 10:30 AM PST

No comments:

Post a Comment