国务院公告:4月4日举行全国性哀悼活动


新华社北京4月3日电为表达全国各族人民对抗击新冠肺炎疫情斗争牺牲烈士和逝世同胞的深切哀悼,国务院今天发布公告,决定2020年4月4日举行全国性哀悼活动。在此期间,全国和驻外使领馆下半旗志哀,全国停止公共娱乐活动。4月4日10时起,全国人民默哀3分钟,汽车、火车、舰船鸣笛,防空警报鸣响。

Posted in 随笔 | Tagged , , , , , | Leave a comment

Linux | 文本筛选工具:grep的常规用法


grep是在终端下,从文件中筛选文本最常用的工具.估计大多数人停留在cat file|grep xxx或者grep xxx file的阶段.其实这是个超级强大的工具,今天就进行简单的初探.
操作对象:『The Zen Of Python』

$ python -c 'import this' |tee a.txt
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
  • 其它基本用法
-c count出现次数
-n number显示行
-v 排除
-i 忽略大小写

友情提示,以下演示在有颜色的终端下,效果更佳

  • 匹配后输出前后行
后面(After)一行 -A 1
$ grep 'Unless explicitly' -nA 1 a.txt
13:Unless explicitly silenced.
14-In the face of ambiguity, refuse the temptation to guess.

前面(Before)一行 -B 1
grep 'Unless explicitly' -nB 1 a.txt
12-Errors should never pass silently.
13:Unless explicitly silenced.

前后各一行 -1 或 -C 1
$ grep 'Unless explicitly' -n1 a.txt
12-Errors should never pass silently.
13:Unless explicitly silenced.
14-In the face of ambiguity, refuse the temptation to guess.

$ grep 'Unless explicitly' -nC 1 a.txt
12-Errors should never pass silently.
13:Unless explicitly silenced.
14-In the face of ambiguity, refuse the temptation to guess.
  • 匹配后输出前后几个字符
    查找的字符串为Python
    前三个字符
$ grep -o -P '.{0,3}Python' a.txt
of Python

后五个字符

$ grep -o -P 'Python.{0,5}' a.txt
Python, by 

前三后五个字符

$ grep -o -P '.{0,3}Python.{0,5}' a.txt
of Python, by 
  • 文件匹配
排除a.txt里存在的内容
$ grep -vf b.txt a.txt
  • 高亮匹配项
    检查nginx是否包含模块
$ nginx -V 2>&1 | grep -o with-http_stub_status_module
with-http_stub_status_module
Posted in linux, Mac, Python | Tagged , , , , , , , , , | Leave a comment

ELK | elasticsearch手动调度分片


事出有因:出于节约资源的考虑,ES集群虽然由三个节点组成,但是日志的副本数设为了0,也就是只存一份,不冗余(这很危险).取消副本数以后,ES删除了之前副本,但是由于主副本分布不是那么有规律,于是出现了有的节点数据偏多的情况.接连几天都是同一个节点告警磁盘空间不足,而其它节点却很闲,忍无可忍,才了有想手动调度的想法.

  • 查看节点使用情况
GET _cat/allocation?v&s=disk.avail&h=node,disk.avail,disk.total

node       disk.avail disk.total
es2-master      142gb      7.9tb
es1-master    316.3gb      7.9tb
es3-master    821.7gb      7.9tb

你看看,es3那么闲,为嘛非要可es2一个点落数据

  • 查看es上shard分布情况
GET _cat/shards?v&s=ip,store&h=node,shard,index,store

es2-master 8     nginx-2020.03.29      28gb
es2-master 5     nginx-2020.03.29      28gb
es2-master 2     nginx-2020.03.29      28gb
es2-master 2     nginx-2020.03.30    38.3gb
es2-master 7     nginx-2020.03.30    38.4gb
es2-master 4     nginx-2020.03.30    38.4gb

如上,从es2上找到几个shard大户,就拿他们动手了.
以nginx-2020.03.30为例

  • 禁止自动分配
    因为es有自动均衡机制,会将shard尽可能的分布在不同的节点.如果我们不禁用的话,等后面我们手动调走了shard,es还会把同一个index的其它shard再调度回来(这不瞎耽误工夫吗?)
PUT nginx-2020.03.30/_settings
{
  "settings": {
    "index.routing.allocation.enable": "none"
  }
}
  • 调度走起
    调度的index:nginx-2020.03.30
    调度的shard:2,4,7
    是从第二步里找出来的
POST _cluster/reroute
{
  "commands": [
    {
      "move": {
        "index": "nginx-2020.03.30",
        "shard": 2,
        "from_node": "es2-master",
        "to_node": "es3-master"
      }
    }
  ]
}
  • 验证
    再次查看shard分布信息
GET _cat/shards?v&s=ip,store&h=node,shard,index,store

es2-master               2     nginx-2020.03.30    38.3gb
es2-master               7     nginx-2020.03.30    38.4gb
es2-master               4     nginx-2020.03.30    38.4gb
es2-master -> es3-master 2     nginx-2020.03.31    43.3gb
es2-master -> es3-master 3     nginx-2020.03.31    43.5gb
es2-master -> es3-master 0     nginx-2020.03.31    43.5gb

发现原来的shard不变,新增加了调度的shard

或者
看监控图,发面了流量从es2到es3的激增

Posted in linux | Tagged , , , , , | Leave a comment

Python|常用的时间日期操作


之前有提过,写脚本大多是文本操作,有分割,有合并,有格式化.再有一个就是时间日期操作了.

  • 常用的时间模块有两个
import time
import datetime
  • 常用的日期操作就一个
import time
import datetime

print(time.strftime('%Y-%m-%d %H:%M:%S'))
print(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))

输出:
2020-03-31 21:30:12
2020-03-31 21:30:12
  • 前一天,后一天
import datetime
date_today = datetime.date.today()
print(f'''
昨天:{(date_today + datetime.timedelta(-1)).strftime('%Y-%m-%d')}
今天:{date_today.strftime('%Y-%m-%d')}
明天:{(date_today + datetime.timedelta(1)).strftime('%Y-%m-%d')}
''')
输出:
昨天:2020-03-30
今天:2020-03-31
明天:2020-04-01

f-string语法, 别告诉我没学过
小时的话datetime.timedelta(hours=1)

  • 字符串转日期
import datatime
time_str = '2020-03-31 21:40:05'
time_date= datetime.datetime.strptime(time_str,"%Y-%m-%d %H:%M:%S")

print(f'''
{time_str=}
{time_date=}
timedate='{time_date.strftime('%Y-%m-%d %H:%M:%S')}'
''')

输出:
time_str='2020-03-31 21:40:05'
time_date=datetime.datetime(2020, 3, 31, 21, 40, 5)
timedate='2020-03-31 21:40:05'

不是说常用的是time和datetime吗?怎么后面全是datetime? 哦, time还有一个常用的

  • 暂停运行
#让程序休息2秒
time.sleep(2)

话说这个sleep并发场景慎用哟,至少我司有两次线上事故,就是由这个引起的

Posted in Python | Tagged , , , , | Leave a comment

nginx后端websocket报错400 bad request

  • 现象

WebSocket connection to 'ws://xxx.xxx.xxx/socket/socket.io/?EIO=3&transport=websocket&sid=GR62rU2Ggwa1wt0nAAOt' failed: Error during WebSocket handshake: Unexpected response code: 400

  • 解决
location /socket {
    proxy_pass http://192.168.1.32:7002;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

一般来说400错误,就是上面的问题,如果不是,检查有没有http和https混用的连接

Posted in linux | Tagged , , , , , , , | Leave a comment

Python|f-string让我喜欢Python的原因之一


写脚本,很大一部分工作是在做字符串的处理:分割(split),合并(join),格式化(format).前两部分,各种语言实现,大同小异.而格式化在Python中独树一帜的发明了f-string,它的方便与快捷最终征服了我,成为了Python的支持者.
f-string是Python3.6起才有的功能,这也是为啥写入手Python,直接选择3.7
简单演示:

name='rainbird'
print(f'my name is :{name}.')

输出
my name is :rainbird.

语法:

>>> var='text'
>>> print(f'xxx:{var}')
xxx:text
>>> print(F'xxx:{var}')
xxx:text

以f或F开头后跟一段文本

好吧,演示一段,我儿子幼儿园英语视频的开头:

>>> name='lofty'
>>> age = 5
>>> print(f'''
... Hello, everyone.
... My name is {name}.
... I am {age} years old.
... ''')

Hello, everyone.
My name is lofty.
I am 5 years old.

基本演示完了,还有哪些高级用法呢?

  • 输出{}
>>> print(f'{{花括号}}')
{花括号}
  • 字典使用
>>> user_info={'name':'lofty','age':5}
>>> print(f'''
... Hello, everyone.
... My name is {user_info['name']}.
... I am {user_info['age']} years old.
... ''')

Hello, everyone.
My name is lofty.
I am 5 years old.
  • 固定宽度
number = 5
print(f'''
{number:3} #占三位
{number:03} #占三位不足补0
''')
输出:
  5 #占三位
005 #占三位不足补0
  • 保留小数位
number = 5
print(f'''
{number}
{number:.1f}
''')
输出
5
5.0
  • 对齐
格式 作用
< 左对齐
> 右对齐
^ 居中
number = 5
print(f'''
{number:>3} #右对齐
{number:3} #占三位
{number:03} #占三位不足补0
''')
输出:
  5 #右对齐
  5 #占三位
005 #占三位不足补0
  • 进制转换
格式 作用
b 二进制
o 八进制
d 十进制
x 十六进制(字母小写)
X 十六进制(字母大写)
number = 14
print(f'''
{number:>4b} #二进制
{number:>4o} #八进制
{number:>4d} #十进制
{number:>4x} #十六小写
{number:>4X} #十六大写
''')
输出:
1110 #二进制
  16 #八进制
  14 #十进制
   e #十六小写
   E #十六大写

注意进行了右对齐哟

  • 调试功能
    输出变量名和值(要求Python:3.8)
number = 5
print(f'''
{number=}
''')

输出:
number=5

that's all

Posted in linux, Mac, Python | Tagged , , , , , , , , , | Leave a comment

Python|基于百度API五行代码实现OCR文字高识别率


朋友扔过来一张图片,说在整理试题答案,但是试题是图片,想从网上搜索答案一个一个敲太累了,能不能将图片里的文字提取出来?
我一看这是典型的OCR识别啊,直接祭出神器Tesseract.

tesseract -l chi_sim 4.png stdout
目

二 画 口 “ 口 出

再对比原图一看

哦,不,是不是差的有点儿多?
怎么办呢?tesseract识别不利,肯定是咱玩的不溜,为了识别几张图,再进行一通识别训练是不是有点儿浪费时间?现在都2020年了,各大厂商都提供这种文字识别服务,像我知道的百度都号称50000次/天免费,就它了,开干
第一步 登陆 https://login.bce.baidu.com/

需要百度帐号,是偷是抢,各凭本事吧.
第二步 找到文字识别服务

乖乖,这大厂,就是不一样,产品真多.
第三步 创建一个应用


立即创建
第四步 拿到AppID,API Key,Secret Key

下面是见证五行代码的时刻了
第一步 安装百度Python SDK

pip install baidu-aip

第二步 替换之前拿到 AppID,API Key,Secret Key并修改图片地址

from aip import AipOcr

APP_ID = 'xxx'
API_KEY = 'xxx'
SECRET_KEY = 'xxx'
IMAGE_URL='~/4.png'
client = AipOcr(APP_ID, API_KEY, SECRET_KEY)
with open(IMAGE_URL, 'rb') as fp:
    res         = client.basicGeneral(fp.read())
    for words_arr in res.get('words_result'):
        print(words_arr['words'].replace('.口','.').replace('.回','.'))

第三步 run

$ python ocr-baidu.py 

4、知觉的特性包括()
A.整体性
B.选择性
C.恒常性
D.间接性
E.理解性
5、注意的功能有()
A.调节功能
B.维持功能
C.抑制功能
D.选择功能
E.启动功能


嗯 对比图片,比较完美, 收工!
that's all

Posted in linux, Python | Tagged , , , , , , , , | Leave a comment

Python|虚拟环境及包管理工具pipenv[荐]


前面我们提过Python多版本管理工具pyenv,虚拟环境管理工具pyenv-virtualenv和virtualenv.今天要请出的这位可以说是神器了:通过自动把项目和环境关联实现包管理和环境管理.


优势:

  • 自动创建/进入虚拟环境
  • 自动加载.env里的环境变量
  • 安装包管理,替代requirements.txt,而且方便查看依懒

安装

$ pip install pipenv

查看

$ pipenv --venv
No virtualenv has been created for this project yet!
Aborted!

创建

$ pipenv install --python ~/.pyenv/versions/3.8.2/bin/python3.8
Creating a virtualenv for this project...
Pipfile: /Users/rainbird/testpro/Pipfile
Using /Users/rainbird/.pyenv/versions/3.8.2/bin/python3.8 (3.8.2) to create virtualenv...
⠴ Creating virtual environment...Already using interpreter /Users/rainbird/.pyenv/versions/3.8.2/bin/python3.8
Using base prefix '/Users/rainbird/.pyenv/versions/3.8.2'
New python executable in /Users/rainbird/.local/share/virtualenvs/testpro-_sTYLKQx/bin/python3.8
Also creating executable in /Users/rainbird/.local/share/virtualenvs/testpro-_sTYLKQx/bin/python
Installing setuptools, pip, wheel...
done.
Running virtualenv with interpreter /Users/rainbird/.pyenv/versions/3.8.2/bin/python3.8

✔ Successfully created virtual environment!
Virtualenv location: /Users/rainbird/.local/share/virtualenvs/testpro-_sTYLKQx
Creating a Pipfile for this project...
Pipfile.lock not found, creating...
Locking [dev-packages] dependencies...
Locking [packages] dependencies...
Updated Pipfile.lock (db4242)!
Installing dependencies from Pipfile.lock (db4242)...
  🐍   ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 0/0 — 00:00:00
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.

Profile内容解析

$ cat Pipfile
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]

[packages]

[requires]
python_version = "3.8"

source用来设置仓库地址,即从哪下载虚拟环境所需要的包
packages用来指定项目依赖的包,即你安装了的包
dev-packages用来指定开发环境需要的包,这类包只用于开发过程,不用与生产环境,比如单元测试相关的包,只在开发阶段有用,这样分开便于管理。
requires 中指定目标Python版本

Pipfile.lock

cat Pipfile.lock
{
    "_meta": {
        "hash": {
            "sha256": "7f7606f08e0544d8d012ef4d097dabdd6df6843a28793eb6551245d4b2db4242"
        },
        "pipfile-spec": 6,
        "requires": {
            "python_version": "3.8"
        },
        "sources": [
            {
                "name": "pypi",
                "url": "https://pypi.org/simple",
                "verify_ssl": true
            }
        ]
    },
    "default": {},
    "develop": {}
}

Pipfile.lock中记录了当前虚拟环境中安装的依赖的版本号以及哈希,以保证每次根据这些值装出来的依赖都是一致的,该文件用来保证包的完整性。记住,任何情况下不要手动修改该文件!
项目提交时,可将Pipfile 文件和Pipfile.lock文件一并提交,给其他开发人员克隆下载,他们可以根据此Pipfile文件运行命令pipenv install生成自己的虚拟环境

查看虚拟环境

$ pipenv --venv
/Users/rainbird/.local/share/virtualenvs/testpro-_sTYLKQx

安装Python包
使用pipenv可以轻松优雅地管理项目所依赖的包,下面通过实际使用案例来学习其用法

安装命令

pipenv install requests   #在项目所在虚拟环境中安装requests
pipenv install requests==1.3.1    #安装requests并指定其版本
pipenv install --dev requests      #安装requests包并将其关联为只在开发环境中需要的包

卸载命令

pipenv uninstall requests #在项目所在虚拟环境中卸载requests
pipenv uninstall --all          #从虚拟环境中移除所有已安装的包,但Pipfile.lock文件不受影响
pipenv uninstall --all--dev     #从虚拟环境中卸载所有开发包,并从Pipfile文件中移除这些包

更新命令

pipenv update requests          #在项目中更新requests包
pipenv update                   #更新项目中所有的包
pipenv update --outdated        #查看现有包哪些已经过期

查看命令

pipenv grash                    #显示现有的依赖包
pipenv lock                     #更新Pipfile.lock文件锁定当前环境的依赖版本
上面代码中值得一提的是--dev标志,加了此标志的包只用于开发环境,安装包记录在Pipfile中的dev-package中,如果别人克隆你的Profile文件后使用命令pipenv install创建虚拟环境,默认不会安装dev-package下的安装包,除非使用命令pipenv install --dev
Pipefile 和 Pipefile.lock 都会按照你的操作进行自动的更新,如果需要手动修改包的依赖条件,手工编辑 Pipefile 并进行安装即可。

兼容virtualenv
pipenv可以像virtualenv一样使用命令生成requirements.txt文件。

pipenv lock -r --dev > requirements.txt

同样的,也可以像virtualenv一样通过requirements.txt文件安装包

pipenv install -r requirements.txt

这个命令让我们可以重用以前requirements.txt文件来构建我们新的开发环境,把我们的项目顺利的迁到pipenv。

进入虚拟环境
跟virtualenv一样,要在虚拟环境中运行代码,“激活”虚拟环境。假设可以使用命令pipenv shell进入我们创建的虚拟环境。如下

pipenv shell             # 激活当前虚拟环境,当项目根目录下有 .env 文件时,自动解析添加环境变量
pipenv --where           # 查看当前工作目录
pipenv --venv            # 查看当前虚拟环境路径
pipenv --py              # 查看当前python解释器路径
pipenv --envs            # 查看可用环境变量

执行完命令,命令提示符前出现了如(TestPipenv-tmf99lpc)的前缀,那是我们虚拟环境的名字,这代表我们已经进入了虚拟环境,在其中使用的命令是虚拟环境版本的命令,不是系统的命令。举个例子,如下图

这里进入的是虚拟环境里的Python版本,而不是我们系统环境的Python版本。同样的, 虚拟环境中使用的pip是虚拟环境下的pip,用其安装的库会装在虚拟环境中,不会与系统或其他项目的库冲突。

进入虚拟环境后,我们可以在虚拟环境中运行我们的项目代码,如下

如果想退出虚拟环境,输入exit即可。
如果想在不进入虚拟环境的情况下使用虚拟环境运行代码,可以使用pipenv run命令,如下

pipenv run index.py

删除虚拟环境
如果想删除虚拟环境,可以使用命令pipenv --rm, 如下:

pipenv --rm

值得注意的是,删除了虚拟环境,如果再次使用pipenv shell,会在该目录下创建一个新的虚拟环境,然后再进入虚拟环境。

遇到的问题

  • AttributeError: 'NoneType' object has no attribute 'find_all_python_versions'
pipenv install --python 3.8.2
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/2.7/bin/pipenv", line 11, in <module>
    sys.exit(cli())
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pipenv/vendor/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pipenv/vendor/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pipenv/vendor/click/core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pipenv/vendor/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pipenv/vendor/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pipenv/vendor/click/decorators.py", line 64, in new_func
    return ctx.invoke(f, obj, *args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pipenv/vendor/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pipenv/vendor/click/decorators.py", line 17, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pipenv/cli/command.py", line 254, in install
    editable_packages=state.installstate.editables,
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pipenv/core.py", line 1741, in do_install
    pypi_mirror=pypi_mirror,
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pipenv/core.py", line 574, in ensure_project
    pypi_mirror=pypi_mirror,
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pipenv/core.py", line 494, in ensure_virtualenv
    python = ensure_python(three=three, python=python)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pipenv/core.py", line 397, in ensure_python
    path_to_python = find_a_system_python(python)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pipenv/core.py", line 360, in find_a_system_python
    python_entry = finder.find_python_version(line)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pipenv/vendor/backports/functools_lru_cache.py", line 137, in wrapper
    result = user_function(*args, **kwds)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pipenv/vendor/pythonfinder/pythonfinder.py", line 113, in find_python_version
    return self.system_path.find_python_version(
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pipenv/vendor/pythonfinder/pythonfinder.py", line 54, in system_path
    ignore_unsupported=self.ignore_unsupported,
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pipenv/vendor/pythonfinder/models/path.py", line 451, in create
    ignore_unsupported=ignore_unsupported,
  File "<attrs generated init 0c5e0ca48e6d72e07a67727a626d079225b052cd>", line 38, in __init__
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pipenv/vendor/pythonfinder/models/path.py", line 116, in __attrs_post_init__
    self._setup_pyenv()
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pipenv/vendor/pythonfinder/models/path.py", line 196, in _setup_pyenv
    version_glob_path="versions/*", ignore_unsupported=self.ignore_unsupported
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pipenv/vendor/pythonfinder/models/python.py", line 156, in create
    sort_function=sort_function, version_glob_path=version_glob_path)
  File "<attrs generated init 0d637cc9107620abb7d1640cbc38b38ba03a1912>", line 17, in __init__
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pipenv/vendor/pythonfinder/models/python.py", line 114, in get_versions
    entry = next(iter(version_path.find_all_python_versions()), None)
AttributeError: 'NoneType' object has no attribute 'find_all_python_versions'

解决

rm ~/.pyenv/versions/.DS_Store
Posted in linux, Mac, Python | Tagged , , , , , , , | Leave a comment

cronjob|Web版之gocron配置过程

对于Linux系统管理来说,配置计划任务是常有的事儿,基本直接cronjob走起(linux定时任务之crontab),但是凡事有个度,一个两个还成,如果加一堆就有一点儿尴尬了,一来查看管理不方便,二来不同任务的执行结果也不那么明了,三来添加都觉得费劲.
关键还有一点儿,竟然有人要求能不能五秒执行一次?乖乖,我大cronjbo执行间隔可是分钟级的,有啥事儿非要几秒钟一次?
于是网上找到了这款开源的定时任务管理系统: gocron

功能特性

  • Web界面管理定时任务
  • crontab时间表达式, 精确到秒
  • 任务执行失败可重试
  • 任务执行超时, 强制结束
  • 任务依赖配置, A任务完成后再执行B任务
  • 账户权限控制
  • 任务类型
    • shell任务

      在任务节点上执行shell命令, 支持任务同时在多个节点上运行

    • HTTP任务

      访问指定的URL地址, 由调度器直接执行, 不依赖任务节点

  • 查看任务执行结果日志
  • 任务执行结果通知, 支持邮件、Slack、Webhook

截图

流程图

任务

通知配置

支持平台

Windows、Linux、Mac OS

环境要求

MySQL

下载

releases

版本升级

安装

了解的差不多了,开工,我是Linux的操作ubuntu 18.04

lsb_release -a
LSB Version:    core-9.20170808ubuntu1-noarch:security-9.20170808ubuntu1-noarch
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.4 LTS
Release:        18.04
Codename:       bionic

Mysql安装

这都2020年了,直接docker起一个吧

INNER_IP=`ifconfig eth0|awk 'NR==2{print $2}'`
docker run -dt \
--name=mysql-gocron \
--restart=always \
-p $INNER_IP:3306:3306 \
-p $INNER_IP:33060:33060 \
-v /etc/localtime:/etc/localtime:ro \
-v /etc/timezone:/etc/timezone:ro \
-v /data/mysql-data-gocron:/var/lib/mysql \
mysql/mysql-server:5.7.24

端口监听在内网IP上,调整时区,数据目录挂出来

查看密码

docker logs -f mysql-gocron 
[Entrypoint] MySQL Docker Image 5.7.24-1.1.8
[Entrypoint] No password option specified for new database.
[Entrypoint]   A random onetime password will be generated.
[Entrypoint] Initializing database
[Entrypoint] Database initialized
Warning: Unable to load '/usr/share/zoneinfo/iso3166.tab' as time zone. Skipping it.
Warning: Unable to load '/usr/share/zoneinfo/leapseconds' as time zone. Skipping it.
Warning: Unable to load '/usr/share/zoneinfo/tzdata.zi' as time zone. Skipping it.
Warning: Unable to load '/usr/share/zoneinfo/zone.tab' as time zone. Skipping it.
Warning: Unable to load '/usr/share/zoneinfo/zone1970.tab' as time zone. Skipping it.
[Entrypoint] GENERATED ROOT PASSWORD: ubjIBOt@D3zQYz.4B=AjiGIzsYg

[Entrypoint] ignoring /docker-entrypoint-initdb.d/*

[Entrypoint] Server shut down
[Entrypoint] Setting root user as expired. Password will need to be changed before database can be used.

[Entrypoint] MySQL init process done. Ready for start up.

[Entrypoint] Starting MySQL 5.7.24-1.1.8

看到密码了吗?不用窃喜,这个密码是不让用的,需要先重设一下

 mysql -uroot -pubjIBOt@D3zQYz.4B=AjiGIzsYg
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 13
Server version: 5.7.24

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.
mysql> SET PASSWORD = PASSWORD('your_new_password');
Query OK, 0 rows affected, 1 warning (0.01 sec)

据说也可以这样

UPDATE mysql.user SET Password=PASSWORD('your_new_password')
           WHERE User='root'; 

gocron 服务端启动

#提前配置目录,并修改权限
mkdir /opt/gocron
chown 100.100 /opt/gocron -R

INNER_IP=`ifconfig eth0|awk 'NR==2{print $2}'`
docker run -dt \
--name gocron \
--restart=always \
-p $INNER_IP:5920:5920 \
-v /opt/gocron/conf:/app/conf \
-v /opt/gocron/log:/app/log \
ouqg/gocron

配置: /app/conf/app.ini
日志: /app/log/cron.log
注意,我把这两个目录挂载到/opt/gocron了,配置文件外挂是个好习惯.
然后就直接访问 0.0.0.0:5920了

镜像不包含gocron-node, gocron-node需要和具体业务一起构建

节点配置

启动

下载
cd /opt
wget https://github.com/ouqiang/gocron/releases/download/v1.5.3/gocron-node-v1.5.3-linux-amd64.tar.gz
tar zxf gocron-node-v1.5.3-linux-amd64.tar.gz
mv gocron-node-linux-amd64 gocron-node-v1.5.3

./gocron-node -allow-root -s gocron-node $INNER_IP:5921

管理界面配置节点

节点名称:写一个好记的名字
主机名:IP地址
端口 :5921可以保持不变
备注:看心情填写
保存

点击测试连接
提示连接成功

添加定时任务
自己摸索吧,注意crontab表达式,多了个秒哟

遇到的问题

  • Error 1130: Host '172.17.0.1' is not allowed to connect to this MySQL server
mysql> select user,host from mysql.user;
+---------------+-----------+
| user          | host      |
+---------------+-----------+
| healthchecker | localhost |
| mysql.session | localhost |
| mysql.sys     | localhost |
| root          | localhost |
+---------------+-----------+
4 rows in set (0.00 sec)

mysql> update mysql.user set host='%' where user='root';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
  • 数据库不存在
mysql> create database gocron;
Query OK, 1 row affected (0.00 sec)
  • 数据库配置写入文件失败
chown 100 /opt/gocron -R
Posted in linux, Mac | Tagged , , , , , , , | Leave a comment

恭喜Kubernetes 1.18发布

Kubernetes 1.18是一个“完美”的版本。为了改善用户体验,我们在beta和 stable 功能改进方面进行了大量工作:增加新的开发和新功能。对alpha,beta和 stable 版进行几乎一样多的增强是一项伟大的成就。这说明,社区在提高Kubernetes的可靠性以及继续扩展其现有功能方面所做的巨大努力。

Kubernetes 1.18主要更新内容
Kubernetes拓扑管理器(Topology Manager ) 升级到Beta版 !
拓扑管理器功能 是1.18版中Kubernetes的beta版本功能,它可以使CPU和设备(如SR-IOV VFs)实现NUMA,这将使你的工作负载在针对低延迟而优化的环境中运行。在引入拓扑管理器之前,CPU和设备管理器会做出彼此独立的资源分配决策,那么可能会导致在多套接字( multi-socket )系统上分配不良,从而导致关键型应用程序的性能下降。

Serverside Apply引入Beta 2版本
Server-side Apply 在1.16中被升级为Beta,在1.18中引入Beta 2版本。这个新版本将跟踪和管理所有新Kubernetes对象的字段更改,从而使你知道更改了什么资源以及何时更改的。

使用IngressClass扩展Ingress,并用IngressClass替换不推荐使用的注释
在Kubernetes 1.18中,Ingress有两个重要的补充:一个新pathType字段和一个新IngressClass资源。该pathType字段允许指定路径应如何匹配。除了默认ImplementationSpecific类型外,还有new Exact和Prefixpath类型。

该IngressClass资源用于描述Kubernetes集群中的Ingress类型。入口可以通过ingressClassName在入口上使用新字段来指定与它们关联的类。这个新资源和字段替换了不建议使用的kubernetes.io/ingress.class注释。

SIG-CLI引入kubectl debug命令
SIG-CLI一直在争论是否需要调试实用程序。随着临时容器(ephemeral containers)的发展,开发人员越来越需要更多类似kubectl exec的命令。该kubectl debug命令的添加(它是Alpha版本,但欢迎你提供反馈),使开发人员可以轻松地在集群中调试其Pod。我们认为这种增加是无价的。此命令允许创建一个临时容器,该容器在要检查的Pod旁边运行,并且还附加到控制台以进行交互式故障排除。

Alpha版本引入Windows CSI
随着Kubernetes 1.18的发布,用于Windows的CSI代理的Alpha版本也已发布。CSI代理使非特权(预先批准)的容器能够在Windows上执行特权存储操作。现在,可以利用CSI代理在Windows中支持CSI驱动程序。

Kubernetes 1.18其他更新
欢迎访问<<kubernetes|中文社区>>

转载请注明: 转自Rainbird的个人博客
   本文链接: 恭喜Kubernetes 1.18发布

Posted in linux, Mac | Tagged , , , | Leave a comment