Tuesday, June 22, 2021

V2EX - 技术

V2EX - 技术


[游戏提问] 射击游戏中,子弹轰炸到地面,轰炸造成地面形成一个坑,这个效果怎么实现?

Posted: 22 Jun 2021 04:57 AM PDT

你们的项目启动时间是几秒?

Posted: 22 Jun 2021 04:55 AM PDT

现在手头负责的单体项目是 15-20 秒左右, 有点影响自己的写代码节奏。。加一些启动参数能达到 10-12 秒,感觉变化不大,如果能在 5 秒内启动该多好。
之前待过的公司也都是单体 Java 项目,启动速度慢的能达到 1 分钟, 大家现在手头的项目启动速度都是什么级别的呢? 有没有影响到你们的思维节奏?

面对公司屎山,我内心毫无波澜,因为准备跑路了

Posted: 22 Jun 2021 04:41 AM PDT

从入职第一天起,就发现要面对屎山,但好在 leader 搞这个项目三四年了,感觉还行,每次遇到问题都问他

结果他前阵子离职了。。。。。

最近很艰难,遇到一个不大的问题,我们组内另一个资深工程师也搞不定了。。。。。我俩上周奋斗好几个小时,连本地 server 都 setup 不起来,

面对这陈年屎山,我其实有点不烦躁,就是很迷惘。。。。。

求连体验证码识别方案

Posted: 22 Jun 2021 04:38 AM PDT

比如 aws 的验证码,或者国信证券网上营业厅的验证码。 https://trade2.guosen.com.cn/gxwt/pc/getRandom?rc=0.7285685439680818

cv2 先 2 值化,去干扰线,都没问题,但连体字符搞不定,求切割算法或其他方案。

Rocky Linux 8.4 正式发布了

Posted: 22 Jun 2021 04:16 AM PDT

长时间敲代码,是浅色背景好还是深色背景好?

Posted: 22 Jun 2021 04:09 AM PDT

如题,大家在 ide 里面是深色背景还是浅色的呢? 个人是浅色背景,常用 idea,发现深色背景下的字体对比度不如浅色背景,看久了容易类。老哥们有没有实际的数据说明哪个更好地呀

一个 React re-render 导致 html5 视频无法播放的问题

Posted: 22 Jun 2021 03:59 AM PDT

import React, { useState } from 'react';  export default function App() {   const [video, setVideo] = useState();   const [currentTime, setCurrentTime] = useState(0);    return (     <div className="App">       {video && (         <video           controls           onTimeUpdate={(e) => setCurrentTime(e.target.currentTime)}           src={URL.createObjectURL(video)}           width="250"         />       )}       <p>{currentTime}</p>       <input type="file" onChange={(e) => setVideo(e.target.files?.item(0))} />     </div>   ); } 

一个很简单的 App,加载本地视频,在视频播放的同时,在页面上显示当前视频的时间。但是载入视频后,点击播放按钮,视频无法播放,看起来像是被重绘了,是因为 setCurrentTime 更新了状态数据,从而导致的重绘吗?那我能在哪里做 setCurrentTime 这个操作呢?谢谢鸭!

在线蹲一个正则表达式,求大佬帮助!

Posted: 22 Jun 2021 03:39 AM PDT

限制输入字符串规则:
1.仅支持输入中英文 数字 连字符- 空格字符
2.且不能全为空格字符

list<map>合并问题,面试题

Posted: 22 Jun 2021 03:36 AM PDT

今天面试,问了个题没答上来。。。

题目: 有 listA<map>例如[{"a1":""},{"a2":""},{"a3":""}...],数据量 10W 条

和 listB<map>例如[{"a1":"aaaa"},{"a3":"ssss"},{"a4":"dddd"}...],数据量 15W 条

listA 中 map 的 key 和 listB 中 map 的 key 有些相同,现需要把 listA 里面的和 listB 里面的 key 相同的合并,保留 listB 里面非空的 map,例如合并后为[{"a1":"aaaa"},{"a2":""},{"a3":"ssss"},{"a4":"dddd"}...]

数据量比较大,不让用双层循环。

这个怎么做啊。。。没思路

群晖用哪种硬盘格式比较好呢?

Posted: 22 Jun 2021 03:35 AM PDT

EXT4 ? BTRFS ?其他? Raid 在磁盘出现故障时,恢复数据的几率大吗? 比如 2 块盘,坏了 1 块,会不会出现一定几率无法恢复 是 1 台 nas 开启 raid 好呢?还是 2 台 nas 备份好呢

请教一个 nginx 请求方面的问题

Posted: 22 Jun 2021 03:28 AM PDT

我用 gunicorn+django 部署了一个项目。前端页面调接口 nginx 提示 error:

[alert] 8#8: *12811 zero size buf in writer t:1 r:1 f:0 000056152536F2F0 000056152536F2F0-000056152536F2F0 0000000000000000 0-0 while sending to client 

nginx 配置如下:

   ssl_certificate   conf.d/letsencrypt/3481255__bolineyecare.com.pem;     ssl_certificate_key  conf.d/letsencrypt/3481255__bolineyecare.com.key;     ssl_session_timeout 5m;     ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;     ssl_protocols TLSv1 TLSv1.1 TLSv1.2;     ssl_prefer_server_ciphers on;     charset utf-8;     expires +0d;     add_header Pragma "no-cache";      root  /usr/share/nginx/html/collets_web/dist;     client_max_body_size    2000m;     client_body_buffer_size 2000m;     proxy_read_timeout  20m;      gzip on;     gzip_min_length 4k;     gzip_buffers 4 16k;     gzip_comp_level 6;     gzip_types text/plain application/x-javascript text/css application/xml application/javascript application/json;     gzip_vary on;     gzip_http_version 1.1;     # rewrite ^/$ /admin/ last;     location /api/purchasing/ {        proxy_pass    http://127.0.0.1:9527/api/purchasing/;         proxy_redirect    off;         proxy_set_header    Host    $host;         proxy_set_header    X-Real-IP    $remote_addr;         proxy_set_header    X-Forwarded-For    $proxy_add_x_forwarded_for;         add_header    Cache-Control no-store;         client_max_body_size    2000m;     } 

这两天 baidu 、google 都还没有找到问题。有一种说法是数据的问题。

如何以最快速度加载 H5 页面,考虑网络不佳的情况?

Posted: 22 Jun 2021 03:26 AM PDT

如题,公司在做一个类似收钱吧的产品

需要用户扫一个二维码,加载微信公众号下的付款页面

页面内容是一个简单的数字键盘,用于输入付款的金额

这个过程有一个微信授权的跳转,大概 200ms 左右

服务器页面的响应大概 400ms 左右

这是正常网络的情况,但是会有弱网络的情况,比如小县城的菜市场

目前是单台服务器, 加载的 js 放了 cdn,然后还有个商家上传的 logo,压缩过

老板的问题是,为什么别人(收钱吧)在(菜市场)打开很快,而我们的很慢?

求教各位大佬,还有什么办法可以加快页面加载速度 ?

阿里云的 SLB 负载均衡+高可用的服务,感觉是为了高并发和弹性扩容设计的,用在提高加载速度上效果是否明显?

求助,神奇的 css,为何 overflow 了也没有左右滚动条?

Posted: 22 Jun 2021 03:08 AM PDT

设置父 div 的 overflow 为 scroll,如果它的子 div 的 left 设置为 100(从右侧 overflow),那么父 div 就有左右滚动条;如果 left 设置为-100(从左侧 overflow)就没有滚动条了。

这是为什么呢?难道从左侧 overflow 和从右侧 overflow 还有区别吗?(测试了 chrome 和 firefox 都是这样的)


没有左右滚动条:

<div style="position:relative; left:400px;overflow:scroll;width:200px;height:200px;background:red">   <div style="position:relative; left:-100px;top:100px;width:200px;height:200px;background:blue">  </div>  </div> 

有左右滚动条(与上面的唯一的区别是 left 由-100px 改为了 100px):

<div style="position:relative; left:400px;overflow:scroll;width:200px;height:200px;background:red">   <div style="position:relative; left:100px;top:100px;width:200px;height:200px;background:blue">  </div>  </div> 

亚马逊群晖 DS220+ 1591 元值得轻度用户入手吗?

Posted: 22 Jun 2021 03:03 AM PDT

来源小众软件,手机不方便贴图,麻烦大家自行查看

这段代码有办法更优雅一点吗?

Posted: 22 Jun 2021 02:44 AM PDT

  function traverseTree (tree, cb, isNodeFirst) {     if (isNodeFirst) {       for (let i = 0; i < tree.length; i++) {         cb(tree[i], i, tree)         if (tree[i].children && tree[i].children.length > 0) {           traverseTree(tree[i].children, cb)         }       }     } else {       for (let i = 0; i < tree.length; i++) {         if (tree[i].children && tree[i].children.length > 0) {           traverseTree(tree[i].children, cb)         }         cb(tree[i], i, tree)       }     }   } 

账号被盗恶意登录,现在密码改成了 100 位强密码并启用了双重认证,这下安全了吧?

Posted: 22 Jun 2021 02:30 AM PDT

各位在 10 下用 edge 浏览器的时候 怎样才能只登录浏览器不登录 w10 系统账户?

Posted: 22 Jun 2021 01:41 AM PDT

如题。因为在公司使用。所以只想登录 edge 不登录 win10 系统。但是只要我登录了 edge 他就会默认登录 win10.百度了一下没找到方法。。不知道是不是我姿势不对

说一说我的 NAS 方案

Posted: 22 Jun 2021 01:39 AM PDT

最近看待很多 V 站老哥求 NAS 方案,就来说说我的树莓派+移动硬盘方案吧 16 )

价格

  • 1T 移动硬盘: 200+
  • 树莓派 4B: 看配置 200-600 之间

软件方案

  1. SMB
  2. Webdav
  3. ftp

速度

通过 frp 中转速度大概 500-900k(因为我的中转服务器最大带宽只有 3M),没有试过 frp 的 xtcp 的 p2p 打洞方案 1624324454961.jpg

分片存储-细碎设计系列

Posted: 22 Jun 2021 01:37 AM PDT

摘要

系统设计中数据存储模型是核心部分,量级大、QPS 高,通常会通过分库降低 CPU/内存 /磁盘 IO 等系统瓶颈,通过分表降低单表量级过大从而导致的性能问题。那么类似分片存储后从业务角度看会有什么问题?索引法、基因法有是什么呢?

前言

大量的数据存储,常见的水平分片算法:

  • Range
  • Hash

水平分片算法比较普及,只是为了承上启下简单码了一些,懂的同学可以快速跳过!

Range

基于 Unique Key 按照范围分片。切分的维度:

  • 基于固定量级分表,比如千万级分表。tb1:0-1000W 、tb2:1000W- 2000W 。
  • 基于时间维度分表,比如年、月。

优点:

  • 路由策略简单,按照资源范围快速定位到分片。
  • 扩展性,水平创建日后需要的表即可。

不足:

  • 数据分布严重不均匀。
  • 热点数据集中,单表过热。
  • 量级分表,Unique Key 必须满足递增属性。

Hash

基于 Unique Key 取模,均匀分片。

优点:

  • 路由策略简单,Hash Unique Key 快速定位分片。
  • 数据存储&请求量均匀分配,只要 Unique Key 是均匀的。

不足:

  • 扩展性差,扩容时成本较高。

以上是预热部分,当数据分片后对业务带来了哪些问题呢?

例子

Passport Service 几乎是每一个公司必备的基础服务。

之前团队中负责设计 passport 服务时有过 user 存储的思考和设计,简单说说。

Passport Service 是一个非常常见的基础服务,主要提供账号通行证相关能力, 在使用场景中比如登录、注册、登出、登录态校验、更新等,其核心存储是一张 user 表:

比如:

CREATE TABLE `tb_user0` (   `id` int(10) NOT NULL AUTO_INCREMENT COMMENT '表自增 ID',   `uid` bigint(20) NOT NULL DEFAULT '0' COMMENT '用户 ID',   `user_name` varchar(255) NOT NULL DEFAULT '' COMMENT '用户名,不区分大小些;统一成大写,加密后入库',   `pwd` char(40) NOT NULL DEFAULT '' COMMENT '密码',      `......`      `update_time` int(10) NOT NULL DEFAULT '0' COMMENT '最后更新时间',   `create_time` int(10) NOT NULL DEFAULT '0' COMMENT '创建时间',   PRIMARY KEY (`id`),   KEY `idx_uid` (`uid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户主表'; 

user_name 为登录用户名,通常会是手机号,需要脱敏

ok,这张表如何设计呢?

单表实现不合理,结合业务场景,水平分片是必须要有的。

账号量级大,请求量高,需要保证高可用和高一致性。UID 作为 Unique Key,基于 UID 是高频查询,那么就基于 UID 水平分表。

前台服务相对核心的操作:

  • 登录。 基于 user_name+pwd 实现登录,量级占大盘<=1%此处 UID 为结果数据
  • 校验登录态。基于 token 解析出 UID,判断登录态获取用户信息,量级占大盘>= 99%此处 UID 为起始数据

后台服务(MIS 或运营管理后台) 操作:

  • 超多维度检索
  • 批量分页查询

问题

基于 UID 分片,那么问题来了~

  1. 基于 UID 分片,前台服务登录时没有 UID,只有 user_name,不清楚账号数据落在哪张表,遍历扫全库么?性能低的丑陋。

    用 UID 分片,如何高效实现查询?

    这是本文要讨论的问题。

  2. 数据既然分片了,后台服务的多维度检索,跨分片汇总数据分页查询怎么搞?继续遍历全库内存计数么? Mysql 抗的住么?就算 Mysql 抗的住,后台用户等的起么?就算后台用户脾气好,客户端不会超时么?

    如何多分片高效检索汇总?

    这是本文要讨论的问题++。

方案

issue1: 用 UID 分片,如何高效实现查询?

方案一:索引法

思路:UID 可以定位分片,user_name 无法直接定位,那么通过 user_name 定位 UID,进而定位分片。

方案

  • 基于 Mysql 建立索引表,存储 user_name 与 UID 的 Mapping 关系。
  • 登录校验时基于索引表通过 user_name 查询到 UID,然后路由到指定分片获取数据。
  • 索引表属性少,理论上单行小,容量千万级没问题。
  • 整体模型就是:基于 Index 索引表 + Meta 元数据表(分片)

问题:多一次 DB 查询,性能相对降低。


方案二: 持久化缓存映射

思路:接受不了多一次 DB 查询,那就将映射关系持久化到缓存中。

方案:

  • 基于 缓存(Redis)存储映射关系
  • 登录校验时通过 user_name 到缓存中查询 UID,然后路由到指定分片。
  • 如果缓存没有查到,扫全库获取映射关系持久化到缓存

问题

  • 多一次 Redis 查询,其实也没啥。
  • 缓存击穿风险,Cache 中不存在,当高并发请求打进来,全部去 DB 扫全库,引起 DB 压力瞬间陡增。
  • 缓存穿透风险,当 UID 在 Cache 和 DB 中都不存在,并且不断请求,这种攻击也会导致数据库压力过大。

普通场景下,索引+缓存就可以解决大部分问题


方案三:基于 username 生成 uid

思路:不想单独存储映射关系,直接通过 username 生成 uid

方案:这种通过字符串生成 ID 的 Hash 函数很多,f(username) = uid

问题:

  • Hash 碰撞,UID 冲突的风险
  • username 不能更新

方案四: 基因法

思路: 从 username 中提取基因,加入到 uid 生成规则中。

方案:

这里需要引入分布式全局唯一 ID 生成能力,该基因法依赖分布式 ID,后续会输出《分布式发号器》的文字,先简单普及下分布式 ID 生成的一种常见算法,Snowflake 雪花

SnowFlake 算法生成 id 的结果是一个 64bit 大小的整数,它的结构如下图:

在这里插入图片描述

  • 1bit,不用,因为二进制中最高位是符号位,1 表示负数,0 表示正数。生成的 id 一般都是用整数,所以最高位固定为 0
  • 41bit-时间戳,用来记录时间戳,毫秒级
  • 10bit-工作机器 id,用来记录集群+机器 id
  • 12bit-序列号,序列号,用来记录同毫秒内产生的不同 id,支持步长自增。

所谓基因算法就是提取 username 的分片基因,合并到全局唯一的 ID 上,生成一个全新的 UID 。如下图:

在这里插入图片描述

直接上 Demo 源码吧:

Demo 源码全局唯一 ID 基于 SnowFlake 算法生成,对每个 Block 的 Bit 数简单调整了一下。

基础配置:

const ( 	GENE_NODEIDID_BITS int64 = 10	// 机器节点 10Bit 	GENE_SEQ_BITS      int64 = 13	// 同时间同节点序列号 13Bit 	GENE_BITS          int64 = 12	// 分片基因 12Bit  	GENE_NODEID_MAX int64 = -1 ^ (-1 << GENE_NODEIDID_BITS)	// 机器节点最大值 1024 	GENE_SEQ_MAX    int64 = -1 ^ (-1 << GENE_SEQ_BITS)			// 序列号最大值 8192  	// 这块放弃了时间,为了保留基因。timestemp 单位 s,28 个 bit 大约 7 8 年 	GENE_TIMESTEMP_SHIFT       = GENE_NODEIDID_BITS + GENE_SEQ_BITS + GENE_BITS 	GENE_NODEIDID_SHIFT  int64 = GENE_SEQ_BITS + GENE_BITS 	GENE_SEQ_SHIFT       int64 = GENE_BITS  	// 拒绝浪费,珍惜时间 	GENE_EPOCH int64 = 1624258189  	// 默认步长 	GENE_DEFAULT_STEP_LONG = 1 ) 

这是个 Demo,GENE_BITS 位数需要根据分片数量决定,比如分 16 片,那么 GENE_BITS 4 个 bit 就可以

基因 ID 实例:

type GeneID struct { 	m         sync.Mutex	// 读写锁 	timestemp int64				// 当前时间戳 	nodeID    int64				// 机器节点 	seq       int64				// 序列号 	geneID    int64				// 基因 	step      int64				// 序列号增长步长 } 

样本基因提取:

// 基于基因样本提取基因 ID func ExtractGene(geneSample []byte) int64 { 	gene := md5.Sum(geneSample) 	hashGeneValue := fmt.Sprintf("%x", gene)[29:32] 	geneID, _ := strconv.ParseInt(hashGeneValue, 16, 64) 	return geneID } 
  • 样本 Hash 生成 32 位 MD5
  • 取末尾三个字符
  • 将字符串作为 16 进制转化成 int64 000-fff
  • 结果为基因 ID

基于雪花算法生成完整 ID:

func (g *GeneID) Generate() int64 { 	g.m.Lock() 	defer g.m.Unlock()  	now := time.Now().UnixNano() / 1e9 // 纳秒转秒 	if now == g.timestemp { 		g.seq = g.seq + g.step 		if g.seq > GENE_SEQ_MAX { 			for now <= g.timestemp { 				now = time.Now().UnixNano() / 1e9 			} 			g.seq = 0 		} 	} else { 		g.seq = 0 	} 	g.timestemp = now 	return g.timeBlock() | g.nodeBlock() | g.seqBlock() | g.geneBlock() } 

完整 Demo 源码可访问: https://github.com/xiaoxuz/idgenerator

不足: username 不能更新


issue2: 如何多分片高效检索汇总?

思路 1:前后台数据解耦,资源存储隔离,避免后台低效查询引发前台查询抖动。

思路 2:接受数据冗余存储设计,采用其他存储服务作为后台存储组件,数据双写异步写入

思路 3:后台存储组件可以基于数据时效性选择:

  • 时效性要求高:选择Elasticsearch,基于其分布式倒排索引的特性,实时同步前台数据,并为后台服务提供多维度检索和聚合能力。
  • 时效性要求低:选择大数据相关服务,比如 小时级或天级 数据入 Hive

之前基于 Elasticsearch 做过前后台数据隔离设计,大概设计如下:

在这里插入图片描述

基于阿里开源的 Canal 服务实时订阅消费前台 Mysql 的 binlog,将 binlog 发布到 消息队列Kafka中。

下游可以通过 Flink 实时计算服务或者通过 Golang 实现的 Consumer 来消费 Kafka 中的 Binlog,解析并且转存到Elasticsearch

后台服务基于 Elasticsearch 的 RESTful API 实现实时检索和聚合需求。

总结

Issue1: 用 UID 分片,如何高效实现查询?

  • 索引法
  • 缓存映射
  • username 生成 uid
  • 基因法

Issue2:如何多分片高效检索汇总?

  • 前后台资源隔离,冗余存储设计
  • 基于 Es 或大数据相关服务对后台数据进行存储,并提供实时&离线的数据能力。

思考

记忆力好比缓存,记笔记好比落盘。缓存总会失效,硬盘你可以多副本保留。

tips:学习不要光靠脑袋记,沉淀下来记到本子上才是自己的。

在这里插入图片描述

收工

打完收工,感谢阅读!

在这里插入图片描述

react-dnd 有没有用得比较好的兄弟,请教一下?

Posted: 22 Jun 2021 01:28 AM PDT

最近需要实现一个"可以在页面中"拖动的 Panel,我们拿 V2EX 右侧的这个"发帖提示"举例。

PIC_20210622001.jpg

如图,我已经实现了一个 panel,有 header "发帖提示",有内容,就是下面的"主题标题,正文"等等。

  1. 现在我希望这个 panel 可以用鼠标拖动到屏幕 /页面中的任何位置。但是,只有 header 那个"部分"(红色框)能够响应鼠标的拖动。

  2. 发现 react-dnd 组件,是用于 drag & drop 。但是这个貌似很复杂,拖动时,是整个组件都被拖动?能够定制某个"区域",或者某个子组件响应拖动么?或者,需要指定 draggable 的组件,和 droppable 的组件。我这个案例,不需要 target 的位置。

所以,不是很了解 react-dnd 。特意来问问。react-dnd 怎么实现我的需求,或者有没有其它组件能够做到?

p.s. 我找到一个使用起来很简单的组件,react-rnd,这个实现 1 的需求 很容易(试过了),但是,貌似 2 做不到。react-rnd 包含的组件,都是可拖动的。我只想鼠标移动到 header/上面一部分的时候能够拖动就好。 https://github.com/bokuweb/react-rnd

分享一个 App 安装来源追踪工具

Posted: 22 Jun 2021 01:27 AM PDT

作为 APP 的开发者和运营商,都会研究分析渠道的效果。很多 App 在推广的时候,需要分成 N 个渠道来引流,将 H5 落地页分享出去后,我们希望通过一定的技术手段,知道激活或注册用户是从哪个渠道来的。Android 上可以通过打渠道包的形式,将渠道 ID 硬编码到包里做到这一点,但 iOS 上这样做不太现实。

有一个常见的需求就是:在推广渠道相当多的情况下,通过分发 H5 落地页给不同渠道,从每个渠道来的用户,没有任何感知的情况下,后台可以统计到他激活及注册时的渠道 ID (甚至其他任意参数)。

第三方 SDK openinstall 能够解决这个问题

openinstall 能提供哪些服务呢?

1、携带参数安装

为 App 的每一次安装自定义不同的初始化参数,在下载落地页自定义参数,匹配携带参数来区分不同渠道带来的激活用户。通过分发渠道链接给不同渠道,让每个渠道来的用户,没有任何感知的情况下,后台可以统计到他激活及注册时的渠道 ID (甚至其他任意参数)。

2、App 渠道统计

  • 免打包 App 渠道推广统计技术,10 分钟快速集成
  • 仅凭渠道链接即可精确统计任意 App 渠道统计效果
  • 兼容 Android/iOS 企业包、App Store
  • 完美支持广告效果统计、地推统计等
  • 独创实时报表、实时排重,第一时间洞明渠道状况

3、免费服务:快速安装与一键拉起

快速安装:社交分享一键安装,从此告别"右上角打开浏览器",大幅提升安装概率,助力用户增长。在微信、QQ、新浪微博、钉钉、支付宝等社交平台中直接快速下载安装 apk (兼容 iOS )告别'右上角打开浏览器'操作。

一键拉起:实现 web 页面到 App 间的无缝跳转,解决拉新、拉活、留存、转化等问题,一键拉起 App 到指定场景页面,给用户更优更快体验。从外部分享链接打开的页面,可一键唤醒 App,直达指定页面,如一键加入游戏房间、视频播放页、App 活动详情页等;首次安装 App 后也可还原到对应场景页。

部分使用场景:

  • 免填邀请码安装:自动识别邀请来源,提升安装率与 App 推广裂变效率
  • 移动广告效果统计:简单、灵活、上手快,不要 IDFA,可实时排重,及时发现异常渠道
  • 安装后自动加好友:App 老带新邀请活动,促进用户关系链建立
  • App 地推统计:人手一个二维码,精确统计每个地推人员业绩
  • 社交分享效果统计:精准统计每个分享带来的安装量,不再依赖不可靠的点击量
  • CPS 渠道效果统计:精准统计、为分成结算提供准确可靠的依据
  • 快速下载:微信等社交平台中快速下载
  • 一键拉起 App:iOS、安卓无障碍场景还原,唤醒 App 促活
  • Android 多渠道打包统计:无需技术人员,轻松在线制作安卓渠道包

传送门https://www.openinstall.io/

引用 tools.jar 下的类, 编译不过?

Posted: 22 Jun 2021 12:54 AM PDT

代码

import com.sun.tools.javac.util.Abort;   // 来自 tools.jar 中的类  public class Test {     public static void main(String[] args) {         System.out.println("hello world");     } } 

使用 javac 来编译, 报如下错误

程序包 com.sun.tools.javac.util 不存在

使用的是 jdk1.8

有铁子知道原因么?

求教, docker 安装 redis cluster 后, 客户端/redis-cli -c 跳转啥的访问到的是 docker 内部的 ip. 连接失败.

Posted: 22 Jun 2021 12:35 AM PDT

创建了一个 bridge network, 解决了容器之间网络访问问题, 但客户端连接 redis cluster 后, 获取到的节点的 ip 是 docker 分配给容器的 ip. 这肯定访问不了.

有大侠知道解决办法吗.. 头都秃噜皮了.

安卓 recycleview

Posted: 21 Jun 2021 11:48 PM PDT

recycleview FlexboxLayoutManager 可以通过 setMaxLine 设置只显示多少行 ,但是最后的一行的元素宽度会被压缩 有办法不让压缩吗?能展示多少个就多少个

关于 PHP 的 yield 的一个奇怪的问题

Posted: 21 Jun 2021 10:30 PM PDT

最近在学习 PHP yield 相关的知识,遇到了一个搞不懂的问题,直接上代码:

function gen() {     for ($i = 0; $i < 3; $i++) {         echo "For index:$i\n";         $tmp = (yield $i);     } }  $gen = gen(); foreach ($gen as $val) {     echo "Generator return:$val\n"; } echo "Finish\n"; 

上面这段代码会输出:

For index:0 Generator return:0 For index:1 Generator return:1 For index:2 Generator return:2 Finish 

但是,只要在代码里加多一句send的代码,如下:

function gen() {     for ($i = 0; $i < 3; $i++) {         echo "For index:$i\n";         $tmp = (yield $i);     } }  $gen = gen(); foreach ($gen as $val) {     echo "Generator return:$val\n";     $gen->send(++$val); // 这句是新加的代码 } echo "Finish\n"; 

然后输出就会变成(相比原输出,少了一行"Generator return:1"):

For index:0 Generator return:0 For index:1 For index:2 Generator return:2 Finish 

问题:在这个例子里,为什么加了一句 send 后,输出内容就改变了?

请问,这种情况下返回类型声明有必要吗?

Posted: 21 Jun 2021 09:40 PM PDT

// 文件或目录是否存在 public static function exists($path): bool { 	return file_exists($path); } 

这里的 : bool 有必要吗?感谢!

格式化磁盘失败(35)这个是什么问题= =

Posted: 21 Jun 2021 09:11 PM PDT

主板是华擎 j3455,我把 3617 引导装在了 128 的 ssd 上,插上硬盘后安装系统就报 35 错误,无法格式化

如何在一段时间内逐渐降低 Windows 的音量?

Posted: 21 Jun 2021 09:00 PM PDT

有些用户在晚上放音乐时会有这个需求

Linux 下应该可以用 Bash 非常方便地实现

Foobar2000 的一些插件或许也可以实现,但是解决方案和具体软件绑定不太好


请问有什么现成的工具可以实现这一需求吗?

萌新请教一个 ES 字符数组过滤问题

Posted: 21 Jun 2021 07:44 PM PDT

索引中某个字段的值是字符数组,例如"test": ["test1", "test2"],查询的时候怎么过滤数组中某个值,只知道 long 类型可以直接过滤,但是这种复合类型似乎不行,mapping 是
"mappings" : {
"properties" : {
"test" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}

CloudQuery 的数据安全技术运用

Posted: 21 Jun 2021 07:42 PM PDT

随着电力行业信息化的不断发展,其内部信息系统越来越复杂,数据库作为信息系统的核心和基础,承载着越来越多的关键业务信息。同时,国家对信息安全方面的重视程度也逐步加深:2014 年 7 月 2 日,国家能源局发布《电力行业网络与信息安全管理办法》; 2018 年,9 月 13 日,国家能源局发布《关于加强电力行业网络安全工作的指导意见》,内容全面覆盖《网络安全法》、《电力监管条例》及相关法律法规要求,对加强关键信息基础设施安全保护、加强电力企业数据安全保护等方面提出了更高、更严的要求。

H 电力公司经过多年发展,依靠现代化经营管理能力,不断加强了信息化、自动化、系统化的特点,而基于政策指导和信息数据化进程不断加快,H 电力公司更需要对数据进行强制性、可控性保护。

一方面,H 电力公司需要通过不断挖掘数据价值以支撑自身服务质量、工作效率和发展需要;另一方面,又要保证数据在复杂场景、系统之间被安全、合理的访问和使用。

传统安全防护手段无法跨越的鸿沟

根据国家能源局对数据安全的意见及 H 电力公司对数据安全的要求,H 电力公司进行了自查,发现了如下不足:

敏感数据管理不足

随着 H 电力公司信息化建设的持续推进,营销、人资、财务、资产、协同、综合等核心系统中存储着大量的业务往来、用户隐私等重要敏感数据。

H 电力公司内部电力数据传输与共享场景普遍,当前虽然有一些数据脱敏手段,但是主要采用脚本或人工脱敏的方式,脱敏规则不统一,从而导致脱敏效率低下,以及脱敏后数据质量差、数据间关联关系被破坏等一系列问题,需要通过对敏感数据进行专业的脱敏实现,"用、护"结合。

风险行为监控不足

H 电力公司信息化规模庞大、系统繁杂、人员众多,日常工作中发生越权访问、下载或篡改数据等违规操作行为难以及时发现和定位,往往对内部数据安全事件的预防和调查造成困扰。

数据库运维管控不足

H 电力公司的网络复杂、业务特殊、数据库众多,在运维专区中,使用堡垒机来对运维人员进行管理,但这种管理方式在数据安全防护上存在一定问题:运维人员不按操作规范或既定方案进行数据库运维操作、非法导出敏感数据、数据库操作行为没有细粒度的审计记录等。

H 电力公司根据目前数据安全痛点和对现状的深入分析,提出如下需求:

1.实现与现有运维管理流程深度融合,实时监控运维人员数据库操作; 2.实现与现有 SPV 集成,运维人员无需单独申请对数据库访问,保持操作习惯不变; 3.实现细粒度运维管控,控制对象可以是库,可以是表,并可以精准到列;除了传统的增删改查操作外,还可以根据访问的影响行判断是否存在数据窃取、批量删除等高危行为;管控的对象还包括用户、登录 IP 、时间、客户端工具等多种条件; 4.提供用户行为审计,方便及时发现风险隐患; 5.支持动态数据遮蔽防止敏感数据泄漏,查询数据自动显示签名,防止拍照外传。

###没有授权进不去 未经许可拿不走 数据泄漏赖不掉

针对以上 H 电力公司面临的问题,CloudQuery 提出本次项目目标应做到"没有授权进不去,未经许可拿不走,数据泄漏赖不掉"。

根据 H 电力公司对信息安全工作的指示,加强对数据中心数据安全的防护要求,经过深入研究,整理出如下建设思路:

数据脱敏

由于 H 电力公司数据错综复杂,各业务数据流转通道各不相同,按照数据的分级分类标准,在对数据进行共享时,应针对重要数据进行脱敏降级,确保数据接收方不会对数据内容进行二次扩散。

数据库安全管控

通过引入 CloudQuery,对数据库的访问及其他操作行为进行细粒度防御、审计分析,从而全程监控、记录包括非法访问、数据库违规操作、数据批量导出或篡改在内等一系列风险行为,实现对所有数据访问行为进行审计记录,然后通过数据分析技术结合数据操作审计典型策略要求,对风险行为进行挖掘和预警,并可在安全事件发生后,做到准确、高效的溯源定责。

数据库运维与管理

在确保不影响正常开展运维工作的前提下,建立数据库运维操作的审批机制和技术措施。通过 CloudQuery 对所有涉及敏感数据的操作进行限制,强化对数据库运维操作的监管力度,及时阻断越权操作行为的发生,令运维工作实际操作与计划操作保持一致。

对数据运维操作的关键动作进行划分,将那些敏感操作梳理出来并默认禁止。当有变更需求时,通过发起运维审批流程,根据审批小组的审批意见,有序、安全的执行运维操作。

四大核心模块 解决电力行业棘手问题

针对 H 电力公司的系统现状、其数据库安全管控需求及目标,CloudQuery 制定了符合 H 电力公司数据库安全管控目标的解决方案,全面发挥数据库安全管控平台在企业中的价值。

CloudQuery 作为一体化企业数据安全管控平台,是企业数据操作的入口,将组织(包含应用)、数据、安全整合到一个平台,提供一系列数据应用工具辅助应用和 IT 人员完成相关的数据处理和操作,并逐渐培养组织的数据化流程、协作机制,完善组织的数据意识。

CloudQuery 采用以服务组件为单位,面向云的分布式架构,支持高可用模式保持用户使用的连续性,针对 H 电力公司,我们主要将平台划分为四大核心模块:数据处理中心、用户管控中心、监控中心、审计中心。

数据处理中心:广泛的数据库支持,集中管控数据

CloudQuery 支持绝大多数国内外主流数据库以及中间件,目前支持 Oracle 、SQLServer 、MySQL 、PostgreSQL 、Redis 、Hbase 、达梦、RDS for MySQL 等,未来将支持更多种类的数据库及中间件数据源。覆盖 H 电力公司目前使用的主要数据库数据源。同时,CloudQuery 完美支持各数据库特性,契合操作人员日常数据操作习惯。

用一个平台对所有数据操作进行管控,包含登录登出、权限、脱敏、审计、监控、过滤、回退等。内置一系列流程库,可通过 OpenAPI 接口与现有运维管理系统进行对接,实现数据操作 /授权在数据中心内部流转。

对于 H 电力公司的数据脱敏要求,CloudQuery 采用被动脱敏方式,即不改变数据库内容,但查询得到的结果为脱敏后的数据。脱敏按照规则来处理数据,规则分为内置和动态,内置规则只要用户查询的数据中符合系统内部定义的敏感资源,就会被处理;动态规则指系统管理员或者拥有者根据业务自定义,比如订单里的门牌号等。系统支持 5 种脱敏模式设定:替换、掩码、加密、截断后加密和无效化。

脱敏还会应用在以下场景:

  • 导出:导出的数据条目只要符合脱敏设定,那么不管是什么样的文件格式,其内容都会被脱敏;

  • 转储:转储的 SQL 语句,其内容也会被脱敏。

用户管控中心:细粒度权限管控,越权访问需审批

针对可能存在的用户越权访问、非法导出等违规行为,CloudQuery 从不同需求和不同维度进行细粒度权限控制:

  • 操作权限:根据不同的数据源可以分配不同权限,权限由创建连接的账号所拥有的权限列表为全集,可以向下分发,默认加入连接的用户只拥有 select (查询)权限,其他均需要手动赋权或通过流程进行提权申请。

  • 限时限量:可对数据操作进行限时限量权限管控,约定允许操作的开始日期时间和结束日期时间;选择每周能操作的天数;限制用户每个自然周期查询可以得到的记录数,周期结束限量会清零。周期可以灵活配置(天、周、月)。

  • 高危操作限制:对核心业务系统中,重要的有库、表操作非常关键,随意变更可能会带来灾难性影响,在 Cloud Query 将其定义为"高危资源",在其上的所有变更操作(DML 、DDL)都会生成工单;危险性较高的操作,比如 truncate, delete 等等,也同样可被管理员设置为"高危操作"。所有高危操作需要走工单,获取短期的权限,解封操作。

  • 数据过滤:数据库过滤在某种程度上实现了用户的多租,即多个用户使用同一个数据库连接,看到的是不同的数据"视图",千人千面,这极大的增加了权限的灵活性。

  • 数据导出限制:数据导出目前支持 excel 、csv 、txt 、pdf 等格式,支持加密、水印,内容为表格状。结果集导出会受到权限的制约,默认都是关闭状态,如果需要某张表的导出权限可以在流程中向连接管理员发起申请,审批通过后即可进行导出操作。导出同时受到过滤以及脱敏等相关权限的制约,例如当用户在查询结果集时某一列受到脱敏限制,同时在导出时该列也是被脱敏的状态。

审计中心:记录用户行为,风险操作可追踪

CloudQuery 审计系统可跟踪用户在平台上的所有操作,覆盖数据库、流程、权限等方面的查询和变更。审计明细包含用户、连接、库、操作对象、动作、摘要、时间、结果、IP 来源等,可按条件过滤,并支持 Excel 导出。

除了审计明细,系统还支持面向业务的审计分析,可进行多维度的分析,如 UV 、PV 、数据库类型、语句执行时长、慢查询、高危操作。

而通过应用探针或 Cloud Query 提供的审计驱动可对应用的数据操作进行审计分析。相对于面向人的操作审计,应用数据审计主要是站在数据库管理员和安全的视角,对应用的数据访问进行分析,找出违反审计规则的语句,每一个应用包含一个审计视图。主要包含:

  • 审计明细:包含应用 ID 、数据源、库、操作对象、动作、摘要、时间、结果、IP 来源等。

  • 慢查询:数据库语句执行时间连续超过某一个阈值的语句聚合,采样窗口(分钟)可由系统设置。

  • 高危操作:识别出应用中对特定资源的非法操作。

  • 非法地址:根据 IP 来源,识别与数据库不匹配的操作。比如生产环境,只能限于生成应用 IP,不能是测试应用 IP 。

同时应用审计会基于 SQL 模式进行数据分析,支持以下维度的分析:

  • 常用热点表:基于数据库下每张表的读写次数计算出每张表的热度,尽量排序得出热度前十的表进行展示

  • 应用 Top SQL:基于应用的语句执行次数统计出排行前 20 的 SQL,方便 DBA 及时查看进行索引调整等 SQL 优化

  • 应用慢 SQL:基于语句执行时长列出应用的慢 SQL,为 DBA 等相关工作人员进行 SQL 审核提供方便

数据库监控中心:

CloudQuery 可以提供一个集中监控平台,连接管理员可以看到自己管纳连接的数据库负载情况,针对每一种数据源会有不同的监控指标,方便更直观的排查与定位问题。

CloudQuery 的应用价值

没有授权进不去

基于细粒度的权限管控体系,CloudQuery 通过「用户-角色-权限」,在快速授权的同时精准控制每个用户的访问及操作权限,规避了 H 电力公司原先可能面临的越权访问、下载或篡改数据等违规操作行为。

未经许可拿不走

CloudQuery 以独创的「查导分离」作为数据防泄漏的最后一道防线,将导出动作单独形成一种权限类型,与查询动作分离开来。即使 H 电力公司内部人员恶意获取数据也无法将数据落地至 PC 电脑,更别提在企业内部甚至外部进行流通。

数据泄露赖不掉

CloudQuery 作为企业内部的第四道安全防护门。对平台内部众多操作进行埋点,保证 H 电力公司的用户每一个动作都可追踪、可溯源。一旦有用户执行恶意语句或误操作可以及时定位到问题用户及用户 PC IP 。同时,CloudQuery 辅助以告警模块,从不同风控视角来监测当前平台内用户的操作风险性,可以让 H 电力公司在发生数据泄漏时间后快速、精准定位到责任人,及时还原丢失数据。

从 H 电力公司的应用可见,CloudQuery 站在企业角度,根据内部数据流向提供全链路的干涉跟踪保护机制,贯穿数据登录、使用、登出整个生命周期。1:1 针对各数据源的终端,可实时对操作的 SQL 执行拦截、分析、审计、告警等操作,精确到人和应用。避免延后追溯,避免安装堡垒机客户端,也避免审计记录和录像的对比,极大的提高了审计效率和用户体验,让企业内部数据运转更加流畅、安全。

官网地址:http://cloudquery.club/

PDF 去水印

Posted: 21 Jun 2021 07:42 PM PDT

看领域驱动设计时,google 搜索下载了一本 PDF,每一页都印着水印,学习本身就是枯燥的事情,在加上这洗脑水印,着实令人不爽。试了很多网站和 APP 去水印的功能 都不能去掉,就萌生了学一下 PDF 语法,自己实现 PDF 去水印

有同感的同学可以用一下我博客里的 PDF 去水印功能。

免费 PDF 去水印_douyacun

已经实现:

  • 删除 图片 /文字 /图形 水印

未实现:

  • PDF 可以是纯图片的,水印如果印在图片上,不支持去掉图片上的水印。
  • 大于 10M 以上的文件,小服务器支撑不起,发邮箱线下帮忙处理

VLOOK 10.5 发布!表格自动排版特性又上新了~好用实用的 Markdown 主题包与插件

Posted: 21 Jun 2021 05:31 PM PDT

VLOOK™ 是针对 ![Typora] Typora[^Typora] (跨平台 Markdown 编辑器)的 主题包增强插件(针对导出的 HTML 文件)。

VLOOK™ 属于开源软件(遵从 MIT License),也是 ![OSChina]开源中国 推荐的国产开源产品、Typora 的首个增强插件。

VLOOK™ 的所有特性清单,详见快速入坑 → 一键进入

Markdown 粉最喜欢 VLOOK 「表格自动化排版」特性,今天又上新了!

在 V10.5 版本中,可以实现快速设置表格列头自动重复出现了~这个对于长表格、带行分组的表格绝对是友好的助攻。


完整的更新日志如下:

表格

  • (+新增)表格列头支持标记为重复显示 详情
  • (*修复)无行自动编号时非分组单元格的缩进问题
  • (*修复)列头中间内容存在格式(如高亮、换行),会导致列合并异常
  • (*修复)设置列格式时,单元格部分内容为高亮时不应转换为单元格高亮

主题、动效

  • (+新增)成功复制代码块内容的显示高亮动效
  • (^完善)支持通过文档 URL 参数 effects 设置动效等级 详情
  • (^完善)优化主题包大小
  • (*修复)在线版插件动态切换主题的兼容问题

导航中心、段落导航

  • (^完善)收起导航中心后,增加动画式提示将鼠标移至边缘(可快速浮动显示导航中心)
  • (~调整)为改善操作体验,将双击激活段落导航改为三击鼠标

题注

  • (*修复)表格、代码块以 h6 作为题注时,页内链接无法跳转至该 h6 的问题

其他

  • (^完善)一些小小的代码和性能优化
  • (*修复)其他一些小小的问题

欢迎 Markdown 粉加入 VLOOK™ 的 Q 群


项目托管于:

一个头疼的问题

Posted: 21 Jun 2021 04:35 PM PDT

假设我们现在有 3 个环境 线上 测试 开发

Q1. 当线上出现 bug 我们该如何重现 bug ? 比如中间的数据重现 MQ,redis,数据库等

我觉得只能日志排除,因为想要弄到线上数据一模一样很难

Q2. 测试环境发现 bug 我们该如何重现 bug ?比如中间的数据重现 MQ,redis,数据库等

我觉得看项目规模,但是随着项目越来越大,也只能通过日志排除,很难去同步数据

那么我想问一下, 像大厂这些项目用户千万亿的数据级别,排查 bug 和 bug 重现是怎么实现的呢?

非常好奇。望大佬们指条明路。

有没有啥的,现成的解决方案?

求 V 友推荐个 Hugo 主题~

Posted: 21 Jun 2021 01:08 PM PDT

已经有单独的博客站,所以希望是 Introduction 类型的主题。用于生成 Home Page 。

目前看上的有:

docker 运行 redis, NFS 挂载目录权限不足的问题

Posted: 21 Jun 2021 12:22 PM PDT

NFS 是用的群晖 NAS 创建的 RVJijA.png

运行 jumpserver start 的时候查看日志说是 redis 目录没权限 我加了 privileged: true 参数启动还是无效,我还特意用 docker run 跑了一下也是如此

mkdir -p /opt/jumpserver mount -t nfs 192.168.2.38:/volume1/jumpserver /opt/jumpserver 
docker run -d -t \ -v /opt/jumpserver/redis/data:/data \ --privileged=true \ --name redis jumpserver/redis:6-alpine 

jumpserver 配置

version: '2.4'  services:   redis:     image: jumpserver/redis:6-alpine     container_name: jms_redis     privileged: true     restart: always     volumes:       - ${VOLUME_DIR}/redis/data:/data       - ${CONFIG_DIR}/redis/redis.conf:/etc/redis.conf     command: ["redis-server", "/etc/redis.conf", "--requirepass", "$REDIS_PASSWORD"]     environment:       REDIS_PORT: $REDIS_PORT       REDIS_PASSWORD: $REDIS_PASSWORD     healthcheck:       test: "redis-cli -h 127.0.0.1 -p $$REDIS_PORT -a $$REDIS_PASSWORD info"       interval: 10s       timeout: 5s       retries: 3       start_period: 10s     networks:       - net 

No comments:

Post a Comment