小程序开发用什么框架好?
Posted: 12 Jun 2021 10:13 AM PDT
我司之前做了款 CRM 现在打算开发移动版本,老板相中的方案是做小程序,主要针对的平台是钉钉和企业微信,想问下现在开发小程序用哪个框架比较好,请描述下真实感受和所遇到的坑。
我个人目前比较倾向于 taro, 原因是名字看起来简洁有力。顺便问一下如果开发手机版本的话大家会考虑什么方案呢,原生的 Android/iOS 还是 flutter ?
复杂的 Python 目录规范
Posted: 12 Jun 2021 09:18 AM PDT
想知道 Python 有没有具体的比较复杂的目录规范
Google 上大致翻了一下,基本都是比较简单的那种。
平时用的大概文件夹名大概有:
一级:bin,data,src
二级:api,db,lib,utils
三级:具体的模块
另外想问如果和前端(TypeScript)合作是否合适放在一个仓库内,怎么放比较合适。
高中生勿喷,感谢。
关于接口返回值设计问题:服务之间内部调用接口的返回值类型需不需要跟客户端接口保持一致?
Posted: 12 Jun 2021 09:12 AM PDT
现在盛行微服务,有些接口是仅供服务之间内部调用的,有些接口是提供给客户端的,那么问题来了,这两种类型的接口返回值类型需要保持一致吗?你们是怎么设计的?
我为什么会有这么疑问呢,因为我在实际开发中发现,如果返回值类型保持一致的话会有一些不方便的地方,比如,客户端接口的返回值一般会有 code,它的值可能会是 200,404,400,500 等等,但服务之间内部调用接口根本不关注这个,只需返回对象里有个布尔类型的变量告诉我调用其他服务到底成功与否就行了,鉴于此,是否可以设计出两种返回值类型?
protobuf gRPC 这种写配置文件生成代码的形式 "流行"的原因是什么?
Posted: 12 Jun 2021 08:44 AM PDT
再比如 mybatis 用 xml 写 sql.
在比如 spring 初期用 xml 做 IOC...
诸如此类. 这么做的目的是什么?
作为一个 python 程序员不是很习惯.
第二个问题是, 为什么讲 go 和 node 什么的 从 gRPC 里面扯出去新搞了一个仓库.
类似的还有 protoc vs protobuf-gen-go
谢谢大佬们.
如何优雅的停止正在处理队列消息的 worker 呢?
Posted: 12 Jun 2021 08:41 AM PDT
一个发送消息的源头服务器,一个队列,两个 worker 。worker 从队列中拿消息进行处理,处理过程中可能会因为数据源出现了更新,因此 worker 需要停止当前的处理并退出。请问有什么设计模式可以应用的吗?技术栈是 Redis (queue)、worker 是 Node 写的。
我目前想到的一个很笨的方法是还是用将正在处理的任务状态存在 Redis 中,当 worker 开始的时候,将这个 taskId:state 键值对的 state 值改成 processing,如果发送消息的源头出现了数据更新,则源头服务器更新 Redis 中的任务状态为 cancel,worker 处理数据其实是个大 loop,所以每次 loop 的时候先检查任务的 state,如果发现是 cancel 了,那就退出 loop 即退出处理。
又或者用 Redis 的 pubsub ?源头服务推送 cancel 的消息,worker 作为 sub 监听,如果碰到 cancel 的通知,就 process.exit?
不依赖 crontab 带 webui 的 cron 服务
Posted: 12 Jun 2021 08:23 AM PDT
迫于小组内唯一会前端的老哥跑路,求前端老哥们给个 VUE 相关的前端速成路线
Posted: 12 Jun 2021 08:01 AM PDT
万年后端开发,js 就日常写过一点 node 玩,知道 ES6 的一些基础语法,求推荐下 VUE 相关的书籍资料以及好用的 webstorm 插件。
顺道问下 css 有相关的成体系的学习内容么。刚写代码的时候粗略的学了些,但是感觉实际写起来完全是靠蒙。
请教目前浏览器 HTTPS 中对称加密使用的是哪种算法?
Posted: 12 Jun 2021 06:55 AM PDT
引言: HTTPS 请求,开始时候是使用 RSA 算法(非对称加密算法)来传输客户端密钥的,后续数据传输,都是使用客户端密钥来加解密(对称加密算法)数据的。
请问这个 HTTPS 请求过程中,使用的 对称加密算法,是哪种对称加密算法?是 DES 吗?
面试被问住了。。。百度了好久,都是只说到,数据部分用了对称加密算法,但是没有具体说,浏览器用的哪种对称加密算法。
还有人记得当年在 V2EX 发《我开发了一款白酒》的程序员吗,融资数亿了
Posted: 12 Jun 2021 06:44 AM PDT
JpaRepository save 方法先查在改(或插入),能限制不查询,仅指定 update 或 insert 么
Posted: 11 Jun 2021 09:00 PM PDT
JpaRepository save 方法默认先查在改(或插入),能限制不查询,仅指定 update 或 insert 么
仿腾讯蓝鲸 CMDB,自己实现了一版 CMDB,已经开源了,欢迎了解,前端 UI 下了功夫,自我感觉不错呢。
Posted: 11 Jun 2021 07:16 PM PDT
今天碰到一个对接 Java rsa pkcs1 用公钥解密,
Posted: 11 Jun 2021 02:17 PM PDT
python 我搜了好久,都是用私钥解密的, 论坛里的大佬有给个资料的吗?
我实在搜不到了
Android 10 ,未授予任何权限,一些 App 会在某些二级目录创建文件
Posted: 11 Jun 2021 02:05 PM PDT
例如 Download 和 Music
那么
浏览器下载文件就可以不需要存储权限
App 能否读取其创建的文件,还是可以读取或修改所有数据,甚至创建次级目录
Android 目录有什么例外吗
c++一个基础问题
Posted: 11 Jun 2021 01:59 PM PDT
std::string str=std::string("5"); std::regex_search(str,res,std::regex(R"(-?(\d+)|(\d+\.\d+))"));
上面这个是对的,下面这个编译报错,ide 提示我说找不到匹配的函数
std::regex_search(std::string("5"),res,std::regex(R"(-?(\d+)|(\d+\.\d+))"));
我不知道如何搜索相关知识点,根据我有限的认知没理解这两个的区别...
这样会不会被搜索引擎惩罚
Posted: 11 Jun 2021 01:07 PM PDT
有个页面,比较复杂,之前用 vue 写的,问题就是搜索引擎无法搜录这种客户端渲染的页面。
现在想的一个办法是,用服务端渲染出来页面内容,只有内容,没有排版和样式,然后客户端再用 vue 重新渲染为正确的页面。
不知道这样会不会被搜索引擎认为是用户看到的和搜索引擎看到的不一样而惩罚。
高可用架构-限流如何实现
Posted: 11 Jun 2021 12:53 PM PDT
What is 限流? 限流顾名思义,限制流量或者说叫流量管制。
很形象的比喻如老式电闸都安装了保险丝,一旦有人使用超大功率的设备,保险丝就会烧断以保护各个电器不被强电流给烧坏。
Why use 限流? 理论上一个完整的对外提供服务的系统架构在设计初期,就要基于上游流量 ,流速 ,高峰期时间点 ,峰值 qps ,还有自身系统的负载能力 ,评估系统的吞吐量 ,并且进行入口流量的管制。
当超出限流阈值时,系统可以采取拒绝服务,排队或者引流等机制, 保证自身一直在健康的负载下。
如果系统没有限流策略,对于突发性的超自身负载的流量,系统只能被动的无奈接受,系统内各个子服务逐渐解体,最后服务整体雪崩。
小概念 Review QPS
Queries Per Second (每秒查询率),每秒查询率 QPS 是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准,在因特网上,作为域名系统服务器的机器的性能经常用每秒查询率来衡量。
RPS
Requests Per Second (每秒发送请求数 /吞吐率),指客户端每秒发出的请求数。阿里云 PTS 对于这个词的解释为 RPS 有些地方也叫做 QPS,在不单独讨论"事务"的情况下可以近似对应到 Loadrunner/jmeter 的 TPS ( Transaction Per Second, 每秒事务数)。
TPS
Transactions Per Second (每秒传输的事物处理个数),即服务器每秒处理的事务数。TPS 一般包括一条消息入和一条消息出,加上一次用户数据库访问。(业务 TPS = CAPS × 每个呼叫平均 TPS )
限流粒度 集群限流 集群限流方式可以归纳为两种
网关层 网关层常见设计,基于 nginx lua module 实现整体管控。下面是简单 lua demo 。
local locks = require "resty.lock" local function limiter() -- ngx dict local limiter = ngx.shared.limiter -- limiter lock local lock = locks:new("limiter_lock") local key = gx.var.host..ngx.var.uri -- add lock local elapsed, err =lock:lock("ngx_limiter:"..key) if not elapsed then return fail("failed to acquire the lock: ", err) end -- limit max value local limit = 5 -- current value local current =limiter:get(key) -- 限流 if current ~= nil and current + 1> limit then lock:unlock() return 0 end if current == nil then limiter:set(key, 1, 1) -- 初始化 else limiter:incr(key, 1) -- +1 end lock:unlock() return 1 end ngx.print(limiter())
了解 lua-resty-lock: https://github.com/openresty/lua-resty-lock
Nginx.conf
http { …… lua_shared_dict limiter_lock 10m; lua_shared_dict limiter 10m; }
应用层 应用层常见通过业务代码实现,基于 Redis 计数, 通过 lua script 保证 redis 执行原子性.
local key = "limiter:" .. KEYS[1] local limit = tonumber(ARGV[1]) local expire_time = tonumber(ARGV[2]) local is_exists = redis.call("EXISTS", key) if is_exists == 1 then if redis.call("INCR", key) > limit then return 0 else return 1 end else redis.call("SET", key, 1) redis.call("EXPIRE", key, expire_time) return 1 end
单机限流 单兵作战,自生自灭,我不倒集群不倒。不依赖存储中间件,基于 local cache 就可以实现简单的本地计数限流,宏观角度观察,只要网关层负载均衡服务高可用,每个节点流量差别不大,只需要关心单个节点的流量管控就可以。
以上是限流粒度分类,下面说说具体的限流算法模型。
限流模型 以上 Demo 都是基于简单的固定时间窗口模型实现限流,但是当出现临界点瞬间大流量冲击,。
常用的模型分类有两种:
时间模型 时间模型分两种:
固定时间模型 上面聊到的各粒度限流模式的 code demo 都是这种方式。
如图(图片来源网络),拉长 timeline,以 QPS 为例,限流 1000QPS,我们会讲 timeline 按照固定间隔分窗口,每个窗口有一个独立计数器,每个计数器统计窗口内的 qps,如果达到阈值则拒绝服务,这是一种最简单的限流模型,但是缺点比较明显,当在临界点出现大流量冲击,就无法满足流量控制。
如图(图片来源网络),在 900ms 和 1100ms 都出现 1000QPS 并发,虽然单个窗口内是符合限流要求,但是实际上临界点处的 QPS 已经打到 2000,服务过载。
滑动时间模型 如图(图片来源网络),为了规避临界点大流量冲击,滑动时间模型会将每个窗口切分成 N 个子窗口,每个子窗口独立计数。这样用w1
+w2
计数之和来做限流阈值校验,就可以解决此问题。
桶模型 桶模型也分两种:
令牌桶模型 令牌桶算法的原理是系统会以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务。不过令牌桶还是允许一定程度的突发传输,这样解决了在实际上的互联网应用中,流量经常是突发性的问题。
Ref: https://en.wikipedia.org/wiki/Token_bucket
如下图(图片来源网络):
算法实现方式有两种:
Ticker 定义一个 Ticker,持续生成令牌并导入桶中。这样问题是会极大的消耗系统资源。如果基于某一维度进行限流,会创建多桶,对应多 Ticker,资源消耗很可怕。 Inert Fill 惰性填充,定义一个 inert fill 函数。该函数会在每次获取令牌之前调用,其实现思路为,若当前时间晚于 lastAccessTime,则计算该段时间内可以生成多少令牌,将生成的令牌加入令牌桶中并更新数据。这样一来,只需要在获取令牌时计算一次即可。 桶内令牌数计数方式
桶内令牌数 = 剩余的令牌数 + (本次取令牌的时刻-上一次取令牌的时刻)/放置令牌的时间间隔 * 每次放置的令牌数
常用令牌桶如: github.com/juju/ratelimit 2K Star
多种填充令牌 方式:
func NewBucket(fillInterval time.Duration, capacity int64) *Bucket
默认令牌桶,fillInterval 每过多⻓时间向桶⾥放⼀个令牌,capacity 是桶的容量,超过桶容量的部分会被直接丢弃。
func NewBucketWithQuantum(fillInterval time.Duration, capacity, quantum int64) *Bucket
和默认方式一样,唯一不同是每次填充的令牌数是 quantum,而不是 1 个。
func NewBucketWithRate(rate float64, capacity int64) *Bucket
按照使用方定义的⽐例,每秒钟填充令牌数。比如 capacity 是 100,⽽ rate 是 0.1,那么每秒会填充 10 个令牌。
多种领取令牌 方式:
func (tb *Bucket) Take(count int64) time.Duration {} func (tb *Bucket) TakeAvailable(count int64) int64 {} func (tb *Bucket) TakeMaxDuration(count int64, maxWait time.Duration) ( time.Duration, bool, ) {} func (tb *Bucket) Wait(count int64) {} func (tb *Bucket) WaitMaxDuration(count int64, maxWait time.Duration) bool {}
如下,我简单实现了一个极简的令牌桶, 速率默认为 QPS 。
TokenBucket Demo Struct 结构 // object type TbConfig struct { QPS int64 // 限制 qps e.g 200 MaxCap int64 // 桶最大容量 e.g:1000 } type TokenBucket struct { *TbConfig m sync.Mutex // 读写锁 available int64 // 可用令牌 lastTime time.Time // 最后一次获取令牌时间 }
Inert Fill func (tb *TokenBucket) fill() error { n := time.Now() timeUnit := n.Sub(tb.latestTime).Seconds() fillCnt := int64(timeUnit) * tb.QPS // 见文下描述 if fillCnt <= 0 { return nil } tb.available += fillCnt // 防止过大溢出 if tb.MaxCap > 0 && tb.available > tb.MaxCap { tb.available = tb.MaxCap } tb.latestTime = n return nil }
桶内令牌数 = 剩余的令牌数**tb.available
** + (本次取令牌的时刻**n
** - 上一次取令牌的时刻**tb.latestTime
) / 放置令牌的时间间隔速率为 qps,所以此处是 1
** * 每次放置的令牌数**tb.QPS
**
漏桶模型 漏桶算法思路很简单,如下图(图片来源网络),水(请求)先进入到漏桶里,漏桶以一定的速度出水,当水流入速度过大会直接溢出,可以看出漏桶算法能强行限制数据的传输速率。
简单的说: 调用方只能严格按照预定的间隔顺序进行消费调用。
Ref: https://en.wikipedia.org/wiki/Leaky_bucket
常用漏桶: https://github.com/uber-go/ratelimit 2.4k Star
对于很多应用场景来说,除了要求能够限制流量的平均传输速率外,还要求允许某种程度的突发传输。
传统的 Leaky Bucket,关键点在于漏桶始终按照固定的速率运行,但是它并不能很好的处理有大量突发请求的场景。
对于这种情况,uber-go 对 Leaky Bucket 做了一些改良,引入了最大松弛量 (maxSlack) 的概念。
当请求间隔时间小于固定的速率时,可以把间隔比较长的请求多余出来的时间 buffer,匀给后面的使用,保证每秒请求数。如果间隔时间远远超出固定速率,那会给后续请求增加超大的 buffer,以至于即使后面大量请求瞬时到达,也无法抵消完这个时间,那这样就失去了限流的意义。所以 maxSlack 会限制这个 buffer 上限。
LeakyBucket Demo 如下,实现了一个极简的非阻塞漏桶。
Struct 结构 // object type LbConfig struct { Rate float64 // 速率 e.g 200: 每秒 200 次请求 MaxSlack int64 // 最大松弛量,可以理解 buffer 时间内最大放行的 qps 。默认为 0 表示不开启松弛量 e.g 10: 如果松弛量大于 10,则松弛量强制为 10 } type LeakyBucket struct { *LbConfig m sync.Mutex // 读写锁 perRequest time.Duration // 速率 bufferTime time.Duration // 多余时间 slackTime time.Duration // 最大松弛时间 lastTime time.Time // 最后一次获取令牌时间 }
无松弛量实现 即严格按照预定时间间隔获取令牌。
func (lb *LeakyBucket) withoutSlack() error { n := time.Now() lb.bufferTime = lb.perRequest - n.Sub(lb.lastTime) // 多余时间如果为正数: 证明前后时间间隔超过预期速率,需要拒绝服务 if lb.bufferTime > 0 { return ErrNoTEnoughToken } else { lb.lastTime = n } return nil }
有松弛量实现 即多余时间匀给后面获取令牌使用。
func (lb *LeakyBucket) withSlack() error{ n := time.Now() // 此处为+= 表示要累计多余时间 lb.bufferTime += lb.perRequest - n.Sub(lb.lastTime) // 多余时间如果为正数: 证明前后时间间隔超过预期速率,需要拒绝服务 if lb.bufferTime > 0 { return ErrNoTEnoughToken } else { lb.lastTime = n } // 允许抵消的最长时间 if lb.bufferTime < lb.slackTime { lb.bufferTime = lb.slackTime } return nil }
Demo 源码 源码 可见 github.com/xiaoxuz/limiter
相关文章 https://www.cyhone.com/articles/analysis-of-uber-go-ratelimit/
https://en.wikipedia.org/wiki/Token_bucket
https://en.wikipedia.org/wiki/Leaky_bucket
收工 打完收工,感谢支持
似乎是 win10 bug 当 smb 无法连接时,在资源管理器增删文件后,都不会自动刷新
Posted: 11 Jun 2021 12:49 PM PDT
为什么 Centos vs FreeBSD 分别跑 nginx 负载压测,性能差别那么大?
Posted: 11 Jun 2021 12:25 PM PDT
VIDEO
明显 FreeBSD 优于 Centos
端午节准备在家直播写代码~
Posted: 11 Jun 2021 11:56 AM PDT
RT..
有人来看吗,在某站,目前在用 React 全家桶写网页版,可能能帮到前端小白打开思路~
迫于之前开了一个前端训练营带新人做项目,然后有人氪金了说项目太难跟不上,又不忍心打击我,说等以后变强了再跟我做项目...然而我觉得已经很基础了,为了抬杠和还债,我决定整一个更简单的项目直播来写.
项目是一个记事本.应该没有比这更简单的实战项目了。
写完了争取半年更新一次,某记的更新频率比我的使用频率还高,神烦..
正好市面上的笔记应用都用不太爽,就自己写一套!
端午节都出去玩了的话我就换个时间 ̄□ ̄||
这个应用是真的适合入门~
后端准备用 nodejs 、fastify, 移动端可能用 Flutter 或者 Uniapp, 桌面端套个 Electron, 通讯加密要有,钱包密码也能存, 最后可能还会用 slate 扩展编辑器,不过不想趟这个坑,有成熟的 md 编辑器推荐吗~
Oracle Cloud free Tier 可以创建最大 24GB 内存的 ARM VM - Ampere A1 Compute
Posted: 11 Jun 2021 11:45 AM PDT
Infrastructure 2 AMD based Compute VMs with 1/8 OCPU and 1 GB memory each. 4 Arm-based Ampere A1 cores and 24 GB of memory usable as one VM or up to 4 VMs. 2 Block Volumes Storage, 200 GB total. 10 GB Object Storage. 10 GB Archive Storage. Resource Manager: managed Terraform. 5 OCI Bastions. https://www.oracle.com/cloud/free/ https://www.oracle.com/cloud/compute/arm/
似乎是新产品,不知道跟 AMD 的免费 VM 比,实际性能怎么样。
问一下大佬们, 如何保证在 windows 系统上面这个 Python 进程最多只有一个在运行
Posted: 11 Jun 2021 10:26 AM PDT
import time import subproctitle while 1: pass
运行该文件 python hello.py , 如果当前系统已经有这个进程在运行了, 则直接这个文件报错不运行或者其它的, 但是如果没有的话则启动这个文件, 一开始用 setproctitle 这个文件, 设置一个专门的进程名字来检测, 但是 setproctitle 在 windows 上好像 失效了, 那么还有什么方法么?
检测浏览器匿名程度的网站,有人知道吗
Posted: 11 Jun 2021 09:57 AM PDT
记得多年以前偶然访问到了一个,能展示出网站获取到的你的 IP 、浏览器默认语言等等很多,好像还会给出你的匿名程度是百分之几的数字,网页还有一个美式漫画是一个人拿着放大镜。
能记得细节就是这些,怎么搜也搜不到了,有没有大神知道这个站,或者类似功能的呀
不是我不想支持 Android 10 的分区存储啊 Orz
Posted: 11 Jun 2021 08:47 AM PDT
我司 App 最近终于打算上架 Google Play 了,因此在做一些准备工作。Google Play 的上架要求是 targetSdkVersion 最低 29,也就是要适配分区存储 /存储隔离。 当然,还有一种临时的方案就是在 application 设置 android:requestLegacyExternalStorage="true"
。不过这显然也不是啥长久之计,我决定还是直接支持为好。
说一下 App 情况:我们本身行为是很干净的,只有在 DCIM 下创建了一个我们的文件夹,用于用户导出的视频。然后再有一个内置的图片 /视频 /音频选择器,供用户导入,预览内容。
我看了一通 Android 自己的 Android 10 兼容文档,和一些相关的适配文章,<del>很快就适配好了</del>。
大致思路是,我们没法直接操作非我们私有目录文件的 File 了,我们能得到的是 Uri,然后需要读就调 contentResolver.openAssetFileDescriptor
之类的方法,操作 FileDescriptor 即可。 看着是不是很简单!我也觉得!
然后我就愉快地开始测试了=。=
然后发现,项目用到的一个第三方框架,一款获取视频某个关键帧画面的框架 FFmpegMediaMetadataRetriever
,在用 FileDescriptor 解析一部分视频时,会发生 Native Crash 。我想着人家是开源项目嘛,我自己琢磨下咋修呗,然后研究了半天,也试了不同的场景,甚至还找到了当年该作者关于这个问题的提问贴,但看了一圈感觉写得没问题啊...
最后放弃了,给作者提了个 Issue 。
我把用到该框架的功能封装了一下改用 Android 自己的 MediaMetadataRetriever 实现了,姑且算是规避了这个问题。
然后,过了两天,我又发现,我如果反复加载视频(对应的用户操作就是在项目列表页反复进入编辑页退出),以前的操作是直接调系统的一个接口 MediaExtractor.setDataSource(filePath)
,没有问题。但是兼容 Android 10 传 uri 后,操作就是先 contentResolver.openAssetFileDescriptor(uri, "r")
,再 MediaExtractor.setDataSource(fileDescriptor)
,然后当操作次数多了后,openAssetFileDescriptor
就有概率阻塞住,需要过很久才会响应。
我依旧对其进行了很久的分析,自然是有 close 的,而且它的几个不同的 setDataSource
函数本质上也是互相调用的,折腾了一圈,最终结论就是似乎不是我的锅...
而且这个只在一部分手机上会出现。比如我自己的小米 11 就正常。 暂时无解。
再然后,今天早上,测试小姐姐又跟我说,在一台测试机上导图片又会 Crash 啦。我看了一下,大致原因是我们的 Gif 支持是用的一个第三方框架 android-gif-drawable
,它在 Android 11 上(也可能是一部分 Android 11 手机)如果传入一张非 Gif 图,会产生 Native Crash 。
我们可以选择先判断 exif 信息之类的,只对 gif 调用。或者再给作者提个 Issue...
所幸我报着试一试的态度更新了库的依赖,解决了问题。而这个版本也是近几个月才更新修复的。
_(:з)∠)_我已经写得身心俱疲了...不知道哪里会不会又有新的兼容性问题,好烦啊......
现在如何安装 GP?
Posted: 11 Jun 2021 07:51 AM PDT
现在的手机如何安装 Google Play ?
web 因公司需求需要学 flutter 的开发,有什么好的建议
Posted: 11 Jun 2021 07:09 AM PDT
最近在网上查了查 说有原生基础比较好上手 前端的话还需要学习学习 原生的一些代码
怎么优雅的实现 TCP Ping?
Posted: 11 Jun 2021 05:34 AM PDT
如题。
是计算使用 Raw Socket 手动发送 SYN 包 与收到 SYN+ACK 包的时间差,还是直接使用更上层的 TCP Socket,直接计算连接建立完成的时间?
安卓 11 的手机,关了“息屏显示”就不能“双击亮屏”了吗?
Posted: 11 Jun 2021 05:29 AM PDT
moto 系的,预装就是 11 的系统,也是第一次用 11 的系统,不关"息屏显示"的时候也不需要双击,随便一点点振动就会亮屏,不胜其烦,关了息屏显示后除非指纹解锁或者按电源键,否则无论怎么双击三击甚至连击,屏都不可能亮。不方便啊,哪里设置的不对或者有什么办法能找回"双击亮屏"吗?谢谢
大佬们, mysql 五百万以上的 join left 关联查询统计很慢 怎么操作
Posted: 11 Jun 2021 05:18 AM PDT
索引已经加了,a 表 people_id 关联 b 表 id, 然后条件是 b 表的某一个字段==1,然后 count(*)
下面是 php 伪代码
$people_ids = Db::name('people_check')->where('admin_id',$value['id'])->column('people_id'); $people1 = Db::name("people")->where('id','in',$people_ids)->where('id_dailu',1)->count(); # 全部检测人数
admin_id 加了索引,id_dailu 加了索引。 没有全表扫描
原先写法是 join left,这个是改过的, 这个更慢。 求大佬分析一波
现阶段使用 Electron 开发的重量级应用有哪些, 是否可以完全切到 centos 上办公.base. Linux
Posted: 11 Jun 2021 05:06 AM PDT
两三年前 electron-forge 很火,不知现在应用生态怎么样了
Mac 下求一个软件,把电脑当做热点,对手机流量进行 MITM
Posted: 11 Jun 2021 04:05 AM PDT
安卓手机直接在 wifi 里面设置代理,很多请求在 Charles 里面抓不到,怀疑这个设置对一些 app 不奏效。
我想直接把电脑作为无线接入点,手机连上,对通过的流量劫持,这样对手机就是透明的了
我知道这里可能有证书的问题,寄希望于该 app 没做证书校验,试一试吧。
请问,在 Mac 上,有没有这样的软件?
有没有什么方法能让 go 写的命令行程序在 windows 上以服务的方式运行
Posted: 11 Jun 2021 04:00 AM PDT
以 windows 服务的方式运行,避免误关闭之类的操作
第一个 Python 程序 | 机选彩票号码+爬取最新开奖号码
Posted: 11 Jun 2021 02:57 AM PDT
(机选彩票号码+爬取最新开奖号码 | 2021-04-21)
因为是自学状态,没有大佬带路, 想知道写的这些代码有木有不规范的,或者说是不应该这么写等等,一开始就想发在 V2 上,但怕丢人....今天想了想还是发出来, 毕竟大佬们的批评才能让我进步么
这个程序作用是<机选三种彩票类型的号码>
程序内包含功能有如下:
自动获取最新的三种彩票的开奖号码 随机生成三种彩票类型的号码 注册 登录 密码加密 数据写入文件 文件中提取数据 时间模块判断早中晚 先上个演示 | 再附上打包后的程序 exe | 再贴上完整源代码
截至 2021-04-20 的最新彩票开奖信息和程序获取的一致,如图:
演示程序下载>>>
点击下载 提取密码:cisj
import re as m_re import os as m_os import time as m_time import random as m_random import easygui as m_easygui import requests as m_requests # 取开奖号码 class HtmlInfo(): def __init__(self): self.browser_header = { "User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36" "(KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"} #福利彩票 self.ddd_nums = {}# 福彩 3D self.ssq_nums = {}# 双色球 self.qlc_nums = {}# 七乐彩 self.urls = [ r'http://kaijiang.500.com/sd.shtml', r'http://kaijiang.500.com/ssq.shtml', r'http://kaijiang.500.com/qlc.shtml' ] self.html_lable = [ r'<span class="span_right">(.*?)</span>',# 开奖日期-0 r'<strong>(.*?)</strong>',# 开奖期号-1 r'<li class="ball_orange">(.*?)</li>',# 福彩 3D-2 r'<li class="ball_red">(.*?)</li>',# 双色球-红-3 r'<li class="ball_blue">(.*?)</li>',# 双色球-蓝-4 r'<li class="ball_red">(.*?)</li>',# 七乐彩-红-5 r'<li class="ball_blue">(.*?)</li>'# 七乐彩-蓝-6 ] def get_HtmlInfo(self, url): try: html = m_requests.get(url, headers=self.browser_header) html.encoding = 'gbk'# 一下午试图想在正则中解决它...cnm,耽误不少时间 except TypeError: print('网络中断或其他原因!') return# 直接中断程序, 函数内用 return | 函数外用 exit() # 取最新的日期 # lottery_date = m_re.findall('<td align="center">(.*?)</td>', html.text, m_re.S) # 取最新的开奖号码 # for loop_urls in range(len(self.urls)): if self.urls[0] == url: # 福彩 3D: 开奖日期, 开奖期号, 开奖号码, 写入字典 self.lottery_date = m_re.findall(self.html_lable[0], html.text, m_re.S)[0] lottery_date_nums = m_re.findall(self.html_lable[1], html.text, m_re.S)[1] lottery_nums = m_re.findall(self.html_lable[2], html.text, m_re.S) # 数据进字典 self.ddd_nums[lottery_date_nums] = lottery_nums # print(self.ddd_nums) if self.urls[1] == url: # 双色球: 号码列表-合并期号, 开奖日期, 开奖期号, 开奖号码 红六个 / 蓝一个, 红蓝号码合并列表 lottery_nums = [] lottery_date = m_re.findall(self.html_lable[0], html.text, m_re.S)[0] lottery_date_nums = m_re.findall(self.html_lable[1], html.text, m_re.S)[1] lottery_nums_red = m_re.findall(self.html_lable[3], html.text, m_re.S)[:6] lottery_nums_blue = m_re.findall(self.html_lable[4], html.text, m_re.S)[:1] # 下面用 extend 插了两次是因为我想把红蓝球变成一个列表, 如果弄成只插一次就会造成列表套列表,很是疑惑 lottery_nums.extend(lottery_nums_red) lottery_nums.extend(lottery_nums_blue) # 数据进字典 self.ssq_nums[lottery_date_nums] = lottery_nums # print(self.ssq_nums) if self.urls[2] == url: # 七乐彩: 号码列表-合并期号, 开奖日期, 开奖期号, 开奖号码 红七个 / 蓝一个, 红蓝号码合并列表 lottery_nums = [] lottery_date = m_re.findall(self.html_lable[0], html.text, m_re.S)[0] lottery_date_nums = m_re.findall(self.html_lable[1], html.text, m_re.S)[1] lottery_nums_red = m_re.findall(self.html_lable[5], html.text, m_re.S)[:7] lottery_nums_blue = m_re.findall(self.html_lable[6], html.text, m_re.S)[:1] lottery_nums.extend(lottery_nums_red) lottery_nums.extend(lottery_nums_blue) # 数据进字典 self.qlc_nums[lottery_date_nums] = lottery_nums # print(self.qlc_nums) # 对密码加密-解密, 上面代码很长 总感觉可以再精简优化下, 目前对于类的使用不是很熟练 class AppCryptos(): def __init__(self): self.token_list = [ '0000000000_' 'bC0>aB3?aA0!aG1%hI1$' 'eK6)dA8&qB4@lC0$bA0&aI0eP1#cC0$' '!@#$%^&*()_+aF0!bG2!cE4_eC1^bE0^aE4@bC0{nB' ] self.enctry_str = ''# 加密数据 self.dectry_str = ''# 解密数据 # 加密 def enctry_AppCryptos(self, key):# key 为传入的密码 for i,j in zip(key, str(self.token_list)): temp_ij = str(ord(i) + ord(j)) + str(self.token_list[0][:15]) self.enctry_str += temp_ij # print(self.enctry_str) return self.enctry_str # 解密 def dectry_AppCryptos(self, key):# key 为传入的密文 for i,j in zip(key.split(str(self.token_list[0][:15]))[:-1], str(self.token_list)): temp_ij = chr(int(i) - ord(j)) self.dectry_str += temp_ij # print(self.dectry_str) return self.dectry_str # EasyGui class EasyGuiUI(): def __init__(self): self.app_config = [ r'AppConfig.ini',# 文件可自定义目录存放,也可以跟主程序走 r'MainConfig.ini',# 文件跟着主程序走 r'config_path=',# 用户自己选择的配置文件目录路径 r'configfile_path=',# 用户自己选择的配置文件目录路径 + AppConfig.ini 路径 r'username=',# 用户昵称 r'userkey='# 加密的程序密码的密文 ] # 取三个数为一注 self.loop_ddd = (0, 9) # 取六个红球,一个蓝球为一注 self.loop_ssq_red = (1, 33) self.loop_ssq_blue = (1, 16) # 七个基本号, 一个特别号为一注 self.loop_qlc = (1, 30) self.box_msg = [ '欢迎进入彩票号码生成器!\n 是否进行程序初始化?\n 自定义配置文件目录或程序默认目录', '选择一个文件夹!', '欢迎使用机选彩票号码程序, 祝您早日中大奖!', '请输入程序密码', '注册成功!', '\n\n\n 点击下方[查看最新开奖号码]按钮以获取开奖号码' ] self.box_title = [ '程序初始化', '激活程序', '登录验证', '机选号码' ] self.indexbox_choices = [ ['0', '确定'],# 用来判断 choices_msg 按钮返回值 ['1', '默认'], ['2', '机选号码'], ['3', '查看最新开奖号码'], ['4', '退出程序'] ] self.indexbox_errmsg = [ '未知错误!', '文件不存在', '', '', '主程序文件失效,请重新运行程序!' ] self.multpasswordbox_fields = [ '*昵称', '*程序密码' ] # 如果函数中已经有相同变量,应该是优先读函数中的, 有点忘记了... # 想起来一个, 相同方法下的变量互相调用之前,得先调用被调用的那个方法 self.temp_enctry_str = ''# 临时存放加密的密文,写入到文件 MainConfig.ini. 如果函数中已经有相同变量,应该是优先读函数中的 self.temp_ext_userkey = []# 临时存放提取出来的密文. self.temp_ext_username = []# 临时存放提取出来的昵称 # 运行程序 初始化界面 | 用户选择目录或者程序直接走默认目录 def init_EasyGuiUI(self): try: with open(self.app_config[1], encoding='utf-8') as init_f1: init_f1.close()# 走个过程就直接关掉, 不占用 EasyGuiUI().reg_EasyGuiUI() except OSError: # 初始界面, 因为检查不到文件 MainConfig.ini, 所以初始化一下 目的是生成 AppConfig.ini 和 MainConfig.ini 两个文件 # 原本还想弄一个判断有无文件 AppConfig.ini, 因为这个文件是可以让用户自定义目录去生成的, # 如果作这个判断就把文件 AppConfig.ini 的目录路径也写到文件 MainConfig.ini 中, 想了下还是没写这个, 只验证有无文件 MainConfig.ini choices_msg = m_easygui.indexbox( self.box_msg[0], self.box_title[0], choices=(self.indexbox_choices[0][1],self.indexbox_choices[1][1]) ) # 判断用户是选择的[确定]按钮, 开始调用 diropenbox() 函数选择目录 if choices_msg == int(self.indexbox_choices[0][0]): choices_path = m_easygui.diropenbox(self.box_msg[1]) # 这里会先生成文件 MainConfig.ini, 避免与下方的 m_os.chdir() 函数冲突 with open(self.app_config[1], 'w', encoding='utf-8') as user_f1: user_f1.write( self.app_config[2] + m_os.getcwd() + ';' + '\n' + self.app_config[3] + m_os.getcwd() + '\\' + self.app_config[1] + ';' ) # 选择目录窗口如果直接关闭在这里做个 TypeError 处理 try: m_os.chdir(choices_path) except TypeError: return # 合并一下选择的目录跟文件名 AppConfig.ini,得到一个完整路径 merge_path = m_os.path.join(m_os.getcwd(), self.app_config[0]) # 根据用户选择的目录直接覆写文件 AppConfig.ini with open(merge_path, 'w', encoding='utf-8') as user_f2: user_f2.write( self.app_config[2] + choices_path + ';' + '\n' + self.app_config[3] + merge_path + ';' ) EasyGuiUI().reg_EasyGuiUI() # 判断用户是选择的[默认]按钮, 直接在程序目录下进行覆写两个文件 MainConfig.ini AppConfig.ini elif choices_msg == int(self.indexbox_choices[1][0]): # 选择[默认] 直接在程序所在目录生成文件 with open(self.app_config[0], 'w', encoding='utf-8') as app_f1,\ open(self.app_config[1], 'w', encoding='utf-8') as app_f2: app_f1.write( self.app_config[2] + m_os.getcwd() + ';' + '\n' + self.app_config[3] + m_os.getcwd() + '\\' + self.app_config[0] + ';' ) app_f2.write( self.app_config[2] + m_os.getcwd() + ';' + '\n' + self.app_config[3] + m_os.getcwd() + '\\' + self.app_config[1] + ';' ) EasyGuiUI().reg_EasyGuiUI() # 注册 def reg_EasyGuiUI(self): # 在启用注册 UI 之前 判断下是否已经进行了注册, 判断文件 MainConfig.ini 中有无 self.app_config[4]/[5]这两个字符串 # 这种判断应该还有更好的写法, 截至学到目前的知识 确实想不出了 with open(self.app_config[1], 'r', encoding='utf-8') as read_f1: #在这个变量出来前, 原地转圈琢磨了好久. read()这个好像并不能用在 if 语句的多重判断中,期望的结果会 False read_f1_temp = read_f1.read() if self.app_config[4] in read_f1_temp and self.app_config[5] in read_f1_temp: return EasyGuiUI().login_EasyGuiUI() # 这下面是原地转圈时琢磨的 # if (self.app_config[4] and self.app_config[5]) in read_f1: # return EasyGuiUI().login_EasyGuiUI() # aa = m_re.search('username=*|userkey=*', i) # if aa: # print(aa.group()) # print(i) # if [read_f1_temp1.strip().find('username=') for read_f1_temp1 in read_f1]: # print('11') # with open(self.app_config[1], 'r+', encoding='utf-8') as read_f2: # if [read_f2_temp1.strip().find(self.app_config[5]) for read_f2_temp1 in read_f2.readlines()]: # return EasyGuiUI().login_EasyGuiUI() reg_values = [] reg_values = m_easygui.multpasswordbox( self.box_msg[2], self.box_title[1], fields=(self.multpasswordbox_fields[0],self.multpasswordbox_fields[1]) ) while True: # 循环后 重置 self.indexbox_errmsg[2]的消息为空字符串 self.indexbox_errmsg[2] = self.indexbox_errmsg[3] # 返回值为 None,结束 if reg_values == None: return # 这块还想写一个昵称只能输入纯英文, 程序密码只能输入纯数字 for i in range(len(self.multpasswordbox_fields)): if reg_values[i] == '' and self.multpasswordbox_fields[i][0] == '*' and self.multpasswordbox_fields[i][0] == '*': self.indexbox_errmsg[2] += (' [%s ] 为必填项,请重新填写!\n' % self.multpasswordbox_fields[i]) if self.indexbox_errmsg[2] == '': break reg_values = m_easygui.multpasswordbox( self.indexbox_errmsg[2], self.box_title[1], fields=(self.multpasswordbox_fields[0],self.multpasswordbox_fields[1]), values=reg_values# 这里是留存填写过的内容,并显示在程序,避免用户二次输入 ) # 联动 enctry_AppCryptos() 加密函数, 对用户输入的<程序密码>进行加密 link_AppCryptos = AppCryptos() link_AppCryptos.enctry_AppCryptos(reg_values[1]) self.temp_enctry_str = link_AppCryptos.enctry_str # 将昵称和加密的程序密码存入文件 MainConfig.ini # 这块应该还要做个文件中是否存在 username 和 userkey 的字符串做对应的写入判断(如果字符串存在多个,或者没有,或者文件不在,或者权限不够等) # 不过这次就简单写一下数据存入文件, 其他的心里写了就行 try: with open(self.app_config[1], 'a', encoding='utf-8') as enctry_f1: enctry_f1.write( '\n' + self.app_config[4] + reg_values[0] + ';' + '\n' + self.app_config[5] + self.temp_enctry_str + ';' ) m_easygui.msgbox(self.box_msg[4]) EasyGuiUI().login_EasyGuiUI() except OSError: m_easygui.msgbox(self.indexbox_errmsg[4]) # print(self.enctry_str) # 登录 def login_EasyGuiUI(self): # 登录这块应该也要写一个取文件中密文的时候来个文件是否存在或文件中需要的字符串是否存在, 心里写了! # 想了下 验证文件这些步骤其实可以单独弄个函数放在那边来调用, 这样代码应该可以精简一些 # 在 open 的时候用'x'模式 检查文件是否存在? login_return_cont = m_easygui.passwordbox(self.box_msg[3], self.box_title[2]) # 读取文件中 userkey 存放的密文 with open(self.app_config[1], encoding='utf-8') as dectry_f1: # for read_line in dectry_f1: ext_userkey = m_re.findall(r'userkey=(.*?);', dectry_f1.read(), m_re.S) # print(ext_userkey) # 联动 enctry_AppCryptos(),进行一次密码加密,然后验证加密好的密文是否存在文件内 link_AppCryptos = AppCryptos() link_AppCryptos.dectry_AppCryptos(ext_userkey[0]) if login_return_cont == link_AppCryptos.dectry_str: EasyGuiUI().panel_EasyGuiUI() elif login_return_cont == None: return else: return EasyGuiUI().login_EasyGuiUI() # 登录成功后调用的, 获取最新开奖号码给面板显示 # 此方法被 panel_EasyGuiUI(self) 方法来调用 def get_nums_ForPanel(self): # 获取最新中奖号码, 为了给面板显示 link_HtmlInfo = HtmlInfo() for loop_urls in range(len(link_HtmlInfo.urls)): link_HtmlInfo.get_HtmlInfo(link_HtmlInfo.urls[loop_urls]) dict_ddd = link_HtmlInfo.ddd_nums dict_ssq = link_HtmlInfo.ssq_nums dict_qlc = link_HtmlInfo.qlc_nums dict_ddd_value = ','.join(list(dict_ddd.values())[0]) dict_ssq_value = ','.join(list(dict_ssq.values())[0]) dict_qlc_value = ','.join(list(dict_qlc.values())[0]) self.marge_msgs_get_nums_ForPanel = ( # ext_username[0] + self.box_msg[2] + '\n' + '第[' + list(dict_ddd)[0] + ']期福彩 3D 开奖号码: ' + dict_ddd_value + '\n' + '第[ ' + list(dict_ssq)[0] + ' ]期双色球开奖号码: ' + dict_ssq_value + '\n' + '第[ ' + list(dict_qlc)[0] + ' ]期七乐彩开奖号码: ' + dict_qlc_value ) # 机选号码, 机选的规则都为:彩票投注中的单式投注! # 此方法被 panel_EasyGuiUI(self) 方法来调用 def get_loopnums_ForPanel(self, keyloopnums): if keyloopnums == 'start': # 机选福彩 3D # 使用列表推导式 把需要的每一个元素转换成字符串,这样做的方式是方便呈现的时候 数字后面自带逗号 # loopnums_1_ddd = '' loopnums_1_ddd = [str(m_random.randint(self.loop_ddd[0],self.loop_ddd[1])) for loop in range(3)] loopnums_1_ddd = ','.join(loopnums_1_ddd)# # 三个数字转换成字符串且用逗号来分割进行展示 # print(loopnums_1_ddd)# 输出一下 机选出来的三个数字 # 机选双色球 # loopnums_2_ssq = [] loopnums_2_red = [str(m_random.randint(self.loop_ssq_red[0],self.loop_ssq_red[1])) for loop in range(6)] loopnums_2_blue = [str(m_random.randint(self.loop_ssq_blue[0],self.loop_ssq_blue[1])) for loop in range(1)] loopnums_2_red.append(loopnums_2_blue[0])# 蓝球合并到红球的列表 loopnums_2_ssq = ','.join(loopnums_2_red)# 定一个新的变量名称 | 七个数字转换成字符串且用逗号来分割进行展示 # print(loopnums_2_ssq)# 输出一下 机选出来且合并后的 红+蓝七个数字 # 机选七乐彩 loopnums_3_red = [str(m_random.randint(self.loop_qlc[0],self.loop_qlc[1])) for loop in range(7)] loopnums_3_blue = [str(m_random.randint(self.loop_qlc[0],self.loop_qlc[1])) for loop in range(1)] loopnums_3_red.append(loopnums_3_blue[0]) loopnums_3_qlc = ','.join(loopnums_3_red) # print(loopnums_3_qlc) # 三个彩种机选的号码合并掉,给 panel_EasyGuiUI() 函数中的 indexbox() 调用 self.marge_msgs_get_loopnums_ForPanel = ( '机选的福彩 3D 号码: ' + loopnums_1_ddd + '\n' + '机选的双色球号码: ' + loopnums_2_ssq + '\n' + '机选的七乐彩号码: ' + loopnums_3_qlc + '\n' + '截屏或拍照后去彩票站购买, 祝你鸿运当头!' ) else: pass # 登录成功后 显示获取的最新彩票号码 | 按钮形式机选号码并以 msgbox() 函数显示给用户 | over! def panel_EasyGuiUI(self): self.get_nums_ForPanel() # self.get_loopnums_ForPanel() # 读取文件中 username 存放的昵称 with open(self.app_config[1], encoding='utf-8') as read_f1: ext_username = m_re.findall(r'username=(.*?);', read_f1.read(), m_re.S) # 加一个时间判断 # 06:00~10:00>早上 10:00~12:00>中午 12:00~18:00>下午 18:00~06:00>晚上 get_time = m_time.localtime() # print(get_time.tm_hour) if 0 <= get_time.tm_hour <= 4: indexbox_msg_time = '凌晨时段,注意休息: ' elif 5 <= get_time.tm_hour <= 10: indexbox_msg_time = '早上好: ' elif 11 <= get_time.tm_hour <= 12: indexbox_msg_time = '中午好: ' elif 13 <= get_time.tm_hour <= 18: indexbox_msg_time = '下午好: ' elif 19 <= get_time.tm_hour <= 23: indexbox_msg_time = '晚上好: ' else: indexbox_msg_time = '奈何桥见: ' choices_msg = m_easygui.indexbox( msg=(indexbox_msg_time + ext_username[0] + self.box_msg[5]), title=self.box_title[3], choices=(self.indexbox_choices[2][1],self.indexbox_choices[3][1],self.indexbox_choices[4][1]) ) while True: if choices_msg == 0: self.get_loopnums_ForPanel('start')# 写这里是因为要每次点击都获取新的随机数 # 按钮返回 0 则去机选随机号码展示给用户 choices_msg = m_easygui.indexbox( msg=self.marge_msgs_get_loopnums_ForPanel, title=self.box_title[3], choices=(self.indexbox_choices[2][1],self.indexbox_choices[3][1],self.indexbox_choices[4][1]) ) elif choices_msg == 1: # 按钮返回 1 则去获取最新号码展示给用户 choices_msg = m_easygui.indexbox( msg=self.marge_msgs_get_nums_ForPanel, title=self.box_title[3], choices=(self.indexbox_choices[2][1],self.indexbox_choices[3][1],self.indexbox_choices[4][1]) ) elif choices_msg == 2: # 直接结束 break else: # 这里比如直接关闭 返回了 None break app_run = EasyGuiUI() app_run.init_EasyGuiUI() # app_run.get_loopnums_ForPanel()
[Angular] ngx-center 单运行时多项目共享依赖解决方案
Posted: 11 Jun 2021 02:45 AM PDT
https://github.com/wszgrcy/ngx-center
本来用 ng 的人就少...估计了解我这个的就更少了. 主要是用来解决当项目足够大时,打包时间膨胀,申请内存膨胀的问题 原理就是先打包依赖(dll),再打包主项目,同时主项目实现了内置的 dll,然后打包子项目,子项目可以使用到内置的 dll 来保持住各种依赖注入... 觉得有啥缺点,不足尽管来提吧 关于 黑苹果 固定启动项问题
Posted: 11 Jun 2021 02:12 AM PDT
电脑两块硬盘,一块安装黑苹果 10.15 ,另一块安装 win10 。黑苹果使用最新 OC_0.7.0 引导 。 问题: 进入引导界面后,按 ctrl+enter ( OC 手册写着是选择默认引导)选择 MACOS,正常进入 MACOS 之后无论冷热启动都会默认进 MACOS,这是正常的 。。。但是,当我选择 win10 启动后(只按 entet 确认,不按 ctrl+enter ) 只要重启,无论冷热都会变成 WIN10 引导,不会默认选择 MACOS 。 这是不是 OC 的 BUG ?还是有解决办法? 配置文件的 AllowSetDefault 已设为 ture 。
求 sql 优化才几万数据查询都破 1s 了
Posted: 11 Jun 2021 01:11 AM PDT
从用户表中按 jifen_all 获取我的排名。
SELECT b.rank FROM ( SELECT t.id, @rownum := @rownum + 1 AS rank FROM (SELECT @rownum := 0) r, (SELECT id FROM fa_bankgy_dsxx_user ORDER BY jifen_all DESC) AS t ) AS b WHERE b.id = 29605;
表
CREATE TABLE `fa_bankgy_dsxx_user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `nickname` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL, `openid` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `avatar` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, `realname` varchar(24) COLLATE utf8mb4_unicode_ci NOT NULL, `mobile` varchar(24) COLLATE utf8mb4_unicode_ci NOT NULL, `province` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL, `city` varchar(30) COLLATE utf8mb4_unicode_ci NOT NULL, `area` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL, `workunit` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL, `exchange_count` int(11) DEFAULT '0', `dati_count` int(11) DEFAULT '0' COMMENT '答题次数', `rank_fen` int(11) DEFAULT '0', `jifen_all` int(255) DEFAULT '0', 累计积分数量 `jifen` int(11) NOT NULL DEFAULT '0', `createtime` int(11) NOT NULL, `updatetime` int(11) NOT NULL, `deletetime` int(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `jifen_all` (`jifen_all`), KEY `openid` (`openid`), KEY `workunit` (`workunit`) ) ENGINE=MyISAM AUTO_INCREMENT=33259 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
jifen_all 加了索引,怎么避全表扫描又能取出排名?
关于 nacos 的几个疑问
Posted: 10 Jun 2021 11:59 PM PDT
由于工作原因最近有在接触 nacos,遇到几个疑问的点:
1 、一般在接入 nacos 配置中心时里面都放什么配置? 据官网文章 典型的应用场景 描述,数据库连接信息、限流阈值和降级开关是很好的实践。
数据库连接信息 是在项目启动时读取的,假设当前是独立的 SpringBoot 的应用(没有使用 SpringCloud ),又无法直接在项目启动时从 nacos 中获取配置。这点在官网 issue 中找到类似的疑问。如果我现在就想把数据库信息托管在 nacos,必须使用 SpringCloud ? 限流阈值和降级开关,关于这点,与将这些信息放在 Redis 、ZK 等中间件,有什么区别? 2 、动态 key 该如何访问? 下面是网提供的例子,访问的静态 key 。简单的 k-v 配置。
@NacosValue(value = "${useLocalCache:false}", autoRefreshed = true) private boolean useLocalCache;
假设现在有个 业务项配置 需要根据 某个用户参数 进行获取(key 里包含动态数据 ),这种场景在 nacos 下面是否可行?假如可行,如何实现?
请教运维大佬, strace -p [pid] 没有任何输出,但是该 pid 占用 CPU 百分百
Posted: 10 Jun 2021 11:44 PM PDT
我们有一套 GatewayWorker 程序,分配 4 条进程服务 昨天更新代码,一段时间之后出现某几条进程 cpu 占用 100%,用 strace 跟踪该 pid,没有任何信息输出,请教大佬们有没有排除问题的思路 初步怀疑是由于客户端某个操作,触发了程序内部的死循环,导致,但是程序大大说没发现有什么死循环的代码
有几个关于 etcd 部署的问题想问问大家
Posted: 10 Jun 2021 09:35 PM PDT
最近发现 master 节点上的组件运行都不正常,最后查到了是磁盘 I/O 性能不行导致 etcd 落盘变慢从而影响了其他组件的运行。我们的 etcd 是运行在虚机机上的,可能有其他的机器 I/O 高影响了 etcd 的机器。
有三个问题问问大家:
1 、你们的 etcd 是运行在和其他 master 节点组件一起部署的吗?
2 、etcd 是运行在虚机上还是物理机?如果是虚机的话会避免和其他虚机部署在同一个物理机吗?
3 、etcd 的数据目录是单独挂盘吗?是机械硬盘还是 SSD 呢?因为我看了 etcd 官网是推荐 etcd 部署在 SSD 上的?
AWS EC2 想用负载均衡器监控一个 HTTP 主机是否工作正常,但一直搞不定
Posted: 10 Jun 2021 08:32 PM PDT
在 AWS 上弄了一个免费的 EC2 实例玩,部署的是 windows server 2019 和 Tomcat8.5
Tomcat 上做了一个非常简单的 webapp,只有一个静态的网页 index.html,http 协议,8080 端口。
安全组和 windows 的防火墙里都把 8080 打开了,并且测试过浏览器也能正常访问这个静态网页。
现在想用负载均衡器监控这个 http 服务是否工作正常,侦听器也设置好了 HTTP 8080,但实例一直无法被监听器 ping 通。明明用浏览器可以打开,实在想不通问题出在哪里。请各位大佬指教。
负载均衡器的监听器设置如下: https://imgtu.com/i/2WEaSe https://imgtu.com/i/2WEdQH
index.html 放在 webapp/test/index.html,浏览器的访问方式是 http://IP 地址:8080/test
麻烦大家帮忙看看问题所在,非常感谢!
No comments:
Post a Comment