Python|openpyxl公式的写入及读取

最近excel研究的比较多,先是字体大小,都是单元格宽度,接着链接的保存及读取,这不又要操作公式了,一并记录下来.

写入

写入比较简单,以SUM这个公式举例了

#/usr/bin/python
#-*- coding: utf-8 -*-
import openpyxl
import os
#将Excel文件放在python同级目录
dir_path    = os.path.dirname(os.path.realpath(__file__))
test_xlsx_w = os.path.join(dir_path,f'''test_write.xlsx''')

wb = openpyxl.Workbook()
sheet = wb.active
sheet.cell(1, 1).value = 1
sheet.cell(2, 1).value = 2
sheet.cell(3, 1).value = '=sum(A1:A2)'

#保存文件
wb.save(test_xlsx_w)

读取

读取要的文件名,是上面写入的那个文件,开工

#/usr/bin/python
#-*- coding: utf-8 -*-
import openpyxl
import os
#将Excel文件放在python同级目录
dir_path  = os.path.dirname(os.path.realpath(__file__))
test_xlsx = os.path.join(dir_path,f'''test_write.xlsx''')
wb = openpyxl.load_workbook(test_xlsx)
sheet = wb.active
print(sheet.cell(3, 1).value)

运行

what?
为啥把公式给我输出了,我需要计算后结果啊?
要实现自动公式计算,需要要读取时添加data_only=True参数,以便只读取数据.

wb = openpyxl.load_workbook(test_xlsx,data_only=True)

不过即使添加了这个参数,读取时得到的结果却为None.

这种情况,将之前的Excel打开,再保存一下就可以了.不知道是不是因为openpyxl生成的xlsx的格式有问题,还是什么原因

总结

开头也说了,写过好几篇操作Excel的文章了,罗列一下:
[Python|openpyxl设置单元格样式]()
[Python|openpyxl单元格设置超链接及读取]()
其实直接点击专辑也可以

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

Python|openpyxl单元格设置超链接及读取

背景

在Excel中,有时为了提高效率会放置一些外部的超链接,方便点击查看.近日遇到Python要读取和设置超链接的情况,记录一下

软件 版本
Python 3.8.2
Openpyxl 2.6.4

读取

通过Python读取超链接要相对简单一些,先准备一个Excel文件,A1里放置一个超链接,然后开工

录入

#/usr/bin/python
#-*- coding: utf-8 -*-
import openpyxl
import os
#将Excel文件放在python同级目录
dir_path  = os.path.dirname(os.path.realpath(__file__))
test_xlsx = os.path.join(dir_path,f'''test.xlsx''')
wb = openpyxl.load_workbook(test_xlsx)
sheet = wb.active
print(sheet.cell(1, 1).value)
print(sheet.cell(1, 1).hyperlink.target)

保存为pyxl_link_read.py执行后输出

rainbird's blog
https://blog.cnrainbird.com/


比较简单,接下来代码创建

写入

excel设置超链接也比较简单,顺手赠一个设置单元格宽度和字体

#/usr/bin/python
#-*- coding: utf-8 -*-
import openpyxl

#将Excel文件放在python同级目录
dir_path    = os.path.dirname(os.path.realpath(__file__))
test_xlsx_w = os.path.join(dir_path,f'''test_write.xlsx''')
wb = openpyxl.Workbook()
sheet = wb.active
sheet.cell(1, 1).value = '''=HYPERLINK("https://blog.cnrainbird.com","rainbird's blog")'''
sheet.cell(1, 1).font  = openpyxl.styles.Font('宋体',size = 16,bold=False,italic=False,strike=False,color='000000')
sheet.column_dimensions['A'].width = 25.0

后话

之前有写过Python|openpyxl设置单元格样式那篇主要设置单元格字体,宽度,颜色等.今天又进一步学习了超链接方法

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

K8S|config自动更新器reloader

背景

在不使用配置中心的情况,我们写应用一般会使用环境变量和配置文件保存程序运行的依赖条件,比如:监听IP,端口等.这类应用迁入k8s时,一般都会通过configmap的方式来进行管理.那么问题来了:configmap修改以后有时需要重启pod以实现让应用重新加载配置的目的,尤其像如果将配置文件放在了configmap里,只能通过滚动更新来实现加载新配置.
reloader的工作便是:当你修改了configmap或secret,它来帮你重启相应的Pod.

部署

默认部署到default名称空间

wget https://raw.githubusercontent.com/stakater/Reloader/master/deployments/kubernetes/reloader.yaml
sed -i 's#RELEASE-NAME#config#g' reloader.yaml
kubectl apply -f reloader.yaml

部署到 kube-system 命名空间下

reloader.yaml

---
# Source: reloader/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: kube-system
  labels:
    app: config-reloader
    chart: "reloader-v0.0.39"
    release: "config"
    heritage: "Tiller"
    group: com.stakater.platform
    provider: stakater
    version: v0.0.39

  name: config-reloader
spec:
  replicas: 1
  revisionHistoryLimit: 2
  selector:
    matchLabels:
      app: config-reloader
      release: "config"
  template:
    metadata:
      namespace: kube-system
      labels:
        app: config-reloader
        chart: "reloader-v0.0.39"
        release: "config"
        heritage: "Tiller"
        group: com.stakater.platform
        provider: stakater
        version: v0.0.39

    spec:
      containers:
      - env:
        image: "stakater/reloader:v0.0.39"
        imagePullPolicy: IfNotPresent
        name: config-reloader
        args:
      serviceAccountName: reloader

---
# Source: reloader/templates/clusterrole.yaml

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  labels:
    app: config-reloader
    chart: "reloader-v0.0.39"
    release: "config"
    heritage: "Tiller"
  name: config-reloader-role
  namespace: kube-system
rules:
  - apiGroups:
      - ""
    resources:
      - secrets
      - configmaps
    verbs:
      - list
      - get
      - watch
  - apiGroups:
      - "apps"
    resources:
      - deployments
      - daemonsets
      - statefulsets
    verbs:
      - list
      - get
      - update
      - patch
  - apiGroups:
      - "extensions"
    resources:
      - deployments
      - daemonsets
    verbs:
      - list
      - get
      - update
      - patch

---
# Source: reloader/templates/rolebinding.yaml

---
# Source: reloader/templates/clusterrolebinding.yaml

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  labels:
    app: config-reloader
    chart: "reloader-v0.0.39"
    release: "config"
    heritage: "Tiller"
  name: config-reloader-role-binding
  namespace: kube-system
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: config-reloader-role
subjects:
  - kind: ServiceAccount
    name: reloader
    namespace: kube-system

---
# Source: reloader/templates/serviceaccount.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  namespace: kube-system
  labels:
    app: config-reloader
    chart: "reloader-v0.0.39"
    release: "config"
    heritage: "Tiller"
  name: reloader
kubectl apply -f reloader.yaml

deployment 使用说明

如果某deployment需要随着configmap的更新而自动重启pods
只需要添加注释reloader.stakater.com/auto: "true"即可:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {APP_NAME}-deployment
  annotations:
    reloader.stakater.com/auto: "true"
... ...

拓展

  • 指定 configmap 更新,滚动更新deployment

configmap中以逗号间隔

kind: Deployment
metadata:
  annotations:
    configmap.reloader.stakater.com/reload: "foo-configmap,bar-configmap,baz-configmap"
spec:
  template:
    metadata:
  • 指定 secret, 与 configmap 配置一致

参考链接

https://github.com/stakater/Reloader

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

ubuntu|编译安装mysql2pgsql

dbsync 项目目标是围绕 PostgreSQL Greenplum ,实现易用的数据的互迁功能。
官方地址:
https://github.com/aliyun/rds_dbsync
提供mysql2pgsql和pgsql2pgsql两个工具.
不过竟然只提供了Centos版或者说rpm版.而我司服务器清一色ubuntu,不能因为这个工具,存在一个异类吧?于是开启了这趟不大顺利的编译之旅

系统

Distributor ID: Ubuntu
Description:    Ubuntu 16.04.6 LTS
Release:        16.04
Codename:       xenial

下载代码

放在src目录是了习惯

cd /usr/local/src
git clone https://github.com/aliyun/rds_dbsync.git

安装mysql的开发包

既然编译安装自然依赖mysql的开发包

apt-get install  mysql-community-embedded-devel

安装pg的开发包

pg的包安装相对麻烦一些,毕竟不常用

echo "deb http://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)-pgdg main" >> /etc/apt/sources.list.d/pgdg.list
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add
apt-get update

apt-get install postgresql-server-dev-9.6
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following packages were automatically installed and are no longer required:
  comerr-dev krb5-multidev libgssrpc4 libkadm5clnt-mit9 libkadm5srv-mit9 libkdb5-8
Use 'sudo apt autoremove' to remove them.
The following additional packages will be installed:
  libpq-dev libpq5 postgresql-client-9.6
Suggested packages:
  postgresql-doc-12 postgresql-9.6 postgresql-doc-9.6
The following NEW packages will be installed:
  postgresql-client-9.6 postgresql-server-dev-9.6
The following packages will be upgraded:
  libpq-dev libpq5
2 upgraded, 2 newly installed, 0 to remove and 52 not upgraded.
Need to get 2,438 kB of archives.
After this operation, 10.8 MB of additional disk space will be used.
Do you want to continue? [Y/n] y
Get:1 http://apt.postgresql.org/pub/repos/apt xenial-pgdg/main amd64 libpq-dev amd64 12.3-1.pgdg16.04+1 [139 kB]
Get:2 http://apt.postgresql.org/pub/repos/apt xenial-pgdg/main amd64 libpq5 amd64 12.3-1.pgdg16.04+1 [172 kB]                                   
Get:3 http://apt.postgresql.org/pub/repos/apt xenial-pgdg/main amd64 postgresql-client-9.6 amd64 9.6.18-1.pgdg16.04+1 [1,343 kB]                
Get:4 http://apt.postgresql.org/pub/repos/apt xenial-pgdg/main amd64 postgresql-server-dev-9.6 amd64 9.6.18-1.pgdg16.04+1 [784 kB]              
Fetched 2,438 kB in 4min 24s (9,223 B/s)                                                                                                        
(Reading database ... 105399 files and directories currently installed.)
Preparing to unpack .../libpq-dev_12.3-1.pgdg16.04+1_amd64.deb ...
Unpacking libpq-dev (12.3-1.pgdg16.04+1) over (9.5.21-0ubuntu0.16.04.1) ...
Preparing to unpack .../libpq5_12.3-1.pgdg16.04+1_amd64.deb ...
Unpacking libpq5:amd64 (12.3-1.pgdg16.04+1) over (9.5.21-0ubuntu0.16.04.1) ...
Selecting previously unselected package postgresql-client-9.6.
Preparing to unpack .../postgresql-client-9.6_9.6.18-1.pgdg16.04+1_amd64.deb ...
Unpacking postgresql-client-9.6 (9.6.18-1.pgdg16.04+1) ...
Selecting previously unselected package postgresql-server-dev-9.6.
Preparing to unpack .../postgresql-server-dev-9.6_9.6.18-1.pgdg16.04+1_amd64.deb ...
Unpacking postgresql-server-dev-9.6 (9.6.18-1.pgdg16.04+1) ...
Processing triggers for man-db (2.7.5-1) ...
Processing triggers for libc-bin (2.23-0ubuntu11) ...
Processing triggers for postgresql-common (173ubuntu0.3) ...
Building PostgreSQL dictionaries from installed myspell/hunspell packages...
Removing obsolete dictionary files:
Setting up libpq5:amd64 (12.3-1.pgdg16.04+1) ...
Setting up libpq-dev (12.3-1.pgdg16.04+1) ...
Setting up postgresql-client-9.6 (9.6.18-1.pgdg16.04+1) ...
update-alternatives: using /usr/share/postgresql/9.6/man/man1/psql.1.gz to provide /usr/share/man/man1/psql.1.gz (psql.1.gz) in auto mode
Setting up postgresql-server-dev-9.6 (9.6.18-1.pgdg16.04+1) ...
Processing triggers for libc-bin (2.23-0ubuntu11) ...

编译

尴尬开始

cd rds_dbsync/dbsync
make
/usr/lib/postgresql/9.6/lib/pgxs/src/makefiles/pgxs.mk:219: warning: ignoring old recipe for target 'clean'
g++ -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -g -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -fPIC -pie -fno-omit-frame-pointer -fPIC -fPIC demo.o pg_logicaldecode.o pqformat.o stringinfo.o utils.o misc.o pgsync.o ini.o -L/usr/lib/postgresql/9.6/lib -lpgcommon -lpgport -L/usr/lib/x86_64-linux-gnu -lpq '-Wl,-rpath,$ORIGIN,-rpath,$ORIGIN/lib,-rpath,$ORIGIN/../lib,-rpath,/usr/lib/x86_64-linux-gnu,-rpath,/usr/lib/x86_64-linux-gnu' -L/usr/lib/x86_64-linux-gnu  -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now  -L/usr/lib/x86_64-linux-gnu/mit-krb5 -Wl,--as-needed  -lpthread -o demo 
/usr/bin/ld: demo.o: relocation R_X86_64_32S against `.rodata' can not be used when making a shared object; recompile with -fPIC
demo.o: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
Makefile:27: recipe for target 'all' failed
make: *** [all] Error 1

网上查到两个同类问题

问题:fileappender.o relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPI
解决:
使用 ar -x liblog4cplus.a 解包
readelf --relocs fileappender.o | egrep '(GOT|PLT|JU?MP_SLOT)' 如果输出为空,则该静态库没有position-independent,需要在该静态库的编译脚本添加 -fPIC

ffmpeg  --enable-shared编译时
libavcodec/mqc.o: relocation r_x86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fpic
ffmpeg编译错误,修改Makefile
121:$$(OBJS-$(1)): CFLAGS  += $(CFLAGS-$(1))
为
121:$$(OBJS-$(1)): CFLAGS  += -fPIC $(CFLAGS-$(1))
重新make,成功。

解决办法都是添加-fPIC
经过一番尝试,发现其实编译过程已经添加了-fPIC,但是始终编译不过
查看demo.cpp发现,里面竟然写死了数据库连接的用户名和密码

看来是测试的demo了,那不是可以直接不编译这哥们儿?
将Makefile中demo相关的代码注释掉

-all: demo.o dbsync-pgsql2pgsql.o mysql2pgsql.o dbsync-mysql2pgsql.o readcfg.o
-       $(CXX) $(CFLAGS) demo.o $(OBJS) $(libpq_pgport) $(RPATH_LDFLAGS) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o demo 
+#all: demo.o dbsync-pgsql2pgsql.o mysql2pgsql.o dbsync-mysql2pgsql.o readcfg.o
+all: dbsync-pgsql2pgsql.o mysql2pgsql.o dbsync-mysql2pgsql.o readcfg.o
+       #$(CXX) $(CFLAGS) demo.o $(OBJS) $(libpq_pgport) $(RPATH_LDFLAGS) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o demo 
        $(CXX) $(CFLAGS) readcfg.o dbsync-pgsql2pgsql.o $(OBJS) $(libpq_pgport) $(RPATH_LDFLAGS) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o pgsql2pgsql
        $(CXX) $(CFLAGS) readcfg.o ini.o mysql2pgsql.o dbsync-mysql2pgsql.o misc.o stringinfo.o $(libpq_pgport) $(RPATH_LDFLAGS) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -L$(mysql_lib_dir) -lmysqlclient -o mysql2pgsql

@@ -36,7 +37,7 @@ package:
        mkdir -p install/bin
        mkdir -p install/lib
        cp -fr pgsql2pgsql install/bin
-       cp -fr demo install/bin
+#      cp -fr demo install/bin
        cp -fr ali_recvlogical.so install/lib
        cp -fr mysql2pgsql install/bin
        cp -fr $(mysql_lib_dir)/libmysqlclient.so* install/lib

再次make,顺利通过

打包二进制

# make package 

mkdir -p install
mkdir -p install/bin
mkdir -p install/lib
cp -fr pgsql2pgsql install/bin
cp -fr ali_recvlogical.so install/lib
cp -fr mysql2pgsql install/bin
cp -fr /usr/lib/x86_64-linux-gnu/libmysqlclient.so* install/lib
cp -fr /usr/lib/x86_64-linux-gnu/libpq.so* install/lib

将生成一个install目录,里面有二进制和lib

验证

#cd install/bin/
#ls
mysql2pgsql  pgsql2pgsql
#./mysql2pgsql 
Failed to load config file
read config file error, insufficient permissions or my.cfg does not exist

看起来工作ok

总结

编译过程看似复杂,其实就卡在一个测试的demo文件上.花了有两个小时研究解决方案.好尴尬.

转载请注明: 转自Rainbird的个人博客
   本文链接: ubuntu|编译安装mysql2pgsql

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

联想员工亲历联想大裁员:公司不是家


转自:
https://it.sohu.com/20040720/n221093232.shtml

  今天,恐怕是联想历史上规模最大的一次大裁员。我们部门9个人,今天送走了三个,还有三个要转岗,剩下三个。整个研究院走了30多人,转岗20多人。这是我经历的第二次所谓战略性调整,有很多感触,却又好像什么都堵在心里,说不出来。干脆简单记录下这段往事,提醒自己。

[联想精细化裁员]

  昨天晚上,研究院秘密召开紧急会议。有20多位“责任经理”参加,我才清楚了整个裁员过程。3月6日启动计划,7日讨论名单,8日提交名单,9-10日hr审核,并办理手续,11日面谈。整个过程一气呵成。

  今天就是面谈日。在b座一层的两个小会议室。进去的人,领导首先肯定他过去的成绩,然后解释战略裁员的意思,然后告知支付的补偿金数额,然后递上所有已经办好的材料,然后让他在解除劳动关系合同上签字。平均每个人20分钟。

  被裁的员工事先都完全不知情。在面谈之前,他们的一切手续公司都已经办完,等他们被叫到会议室的同时,邮箱、人力地图、ic卡全部被注销,当他们知道消息以后,两个小时之内必须离开公司。

  所有这一切,都是在高度保密的过程中进行。即使我是责任经理,我也只知道明天由我陪同的员工----坐在我隔壁办公位的,朝夕相处两年多的一个女孩,邵隽。

[邵隽]

  我不知道昨晚我是怎么过的,心情特别不好。根据公司规定,我不能提前告诉她。只觉得心里堵得慌。和我朝夕相处两年的同事,明天就要被裁员了,而她一点也不知道。开完会打车回家时,我感到特别疲惫。司机开口了:你怎么会累呢?你们这一行挣钱多容易呀。我苦笑了一下,没有回答。

  早上,邵隽比我到得要早。向她问声早上好后,我就心虚的不敢再说一句话了。我照例喂我桌上的小金鱼。研究院乔迁研发大厦的时候,每个人发了两条小金鱼,但这帮粗心的研发人员照顾不周,能活到现在的,实在是不容易。邵隽还拿我的鱼开玩笑,说这整儿一鱼精,居然还能活着。

  我不再说话,坐在电脑边发呆,等待着那一刻的到来。电话终于响了,我走到邵隽面前,先和她握手,再叫她去楼下的会议室。她知道去会议室意味着什么。那两个会议室从早忙到晚,所有进去的人,出来后就直接收拾东西走人。但邵隽一直很平静,因为在她之前,我们部门已经进去两个了。是清涛和她谈的,大家都这么熟了,也不用多说什么,不到五分钟,就结束了所有谈话,在解除劳动关系合同上签了字,走了出来。邵隽是fm365转过来的,经历过365那次疯狂的裁员,她那次也送过好多人,所以她很清楚这一切。

  然后回到办公位的时候,陪她收拾东西。到午饭时间了,她说,先去食堂吃饭吧。但我不忍心告诉她,她的ic卡现在已经被注销了。所以我劝她去外边吃。负责另外一个人的责任经理却直接说出来了,还有人告诉她,人力地图也已经注销了,当时邵隽明显非常失落,感觉突然和公司一点牵连都没有了。她在联想工作三年了,可就在两个小时之内,联想就不再有她的任何痕迹。被公司抛弃了。就这么抛弃了?转眼功夫,就不再是曾经引以为豪的:“联想人”啦?

  中午,部门全体去辣婆婆吃散伙饭。不记得说了些什么。

  下午,我送邵隽到家。路过一个小学门口,堵车,她说,我还从来没有下午从这里走过,从来没见过这群孩子们放学。是呀,我也是每天工作到很晚,白天回家还真不习惯。在她家坐了一会儿,因为我知道她这时候心里肯定非常不好受。她说了很多当年365的事情。是呀,不管你如何为公司卖命,当公司不需要你的时候,你曾经做的一切都不再有意义。我特意多呆了一会儿,听她说话,因为我知道,邵隽虽然表现的很坚强,但我一转身走掉,她很可能会哭的,就像今天裁掉的许多人一样。

[重灾区]

  服务器、职能,是这次裁员的重灾区。其中服务器研究室今后可能就不存在了,今天裁得只剩下5个人。早上我就听说那边已经走空了,有几个人哭了,但我没有过去看。有的人情绪非常激动,因为绝对想不到会落在自己头上,但是,战略裁员的意思就是说,不是以你的业绩作为标准,换句话说,就是没有标准。有好几个原来的大牛人,甚至是当时重金从外面聘请的博士后,也就那么走了,没有一点商量余地。就连服务器研究室的主任都走了。这整个方向不要了,这是谁的错?不知道,但只知道受伤的是最底层的员工,难怪有个清华刚毕业的女孩,哭得一塌糊涂。

  职能的助理几乎走光了。和我熟悉的安欣、秦莉,都还没来得及说再见。现在研究院不设置助理岗位了。前几天在食堂碰见她们,我还称她们是研究院的形象代言人。

  武庄也走了,这是我的老战友了。我初进联想的那个项目组,到现在,还在联想的,只剩下我和郭明亮、金峰了。我还记得,那年,我们项目组被号称是研究院的一面旗帜。因为我们开发的内容管理系统,成功地挽救了fm365。后来365倒了,我们就支持赢时通。后来赢时通也倒了,于是研究院信息工程研究室也就没有了。整个研究室当年的30多号人,到现在,还在原岗位的,只剩下我和王江、于兴业了。武庄非常惨,他的老婆在怀孕,而他自己刚刚买房子。我不敢替他想象未来,因为我不能为他做些什么。

  这次裁员的重点,是新来的员工,和呆了好多年的老联想。工作10年的,奔50的人,也照样该走就走了。我真想和他们谈谈心,50岁的时候被公司抛弃,不知道会有什么样的感触。我不敢想。

  回到家里,和小丁聊天,我才知道,服务器的周密走了,这不是新闻,因为服务器的人走得差不多了,但是她的老公也走了!今天他俩还一起上班的,不知道会不会一起回家。他俩和我住在同一个小区,刚结婚不久,刚买的房。

  我突然想起来二战时某位著名将军说的话:我让士兵上战场的时候,我会把他们想象成一堆蚂蚁,而不是人。因为我一想到他们有妻子、孩子、父母,我就不忍心让他们去送死。不知道领导在讨论名单的时候,是把我们想象成蚂蚁吗?

[到底是谁的错]

  我在联想的这三年,亲眼见到联想从全面扩张,到全面收缩的全过程。当年提出的口号是:高科技的联想,服务的联想,国际化的联想。现在,高科技仅剩下关联应用或者,而且还不知道能不能成功。代表服务的it服务群组被划归为c类业务,自身难保了。软件设计中心也即将和联想没有任何关系了。联想四面出击,却伤横累累。

  是谁的错?是领导的错!包括fm365在内,这些方向都是看好的,都是挣大钱的,但为什么联想会失败?我不想在这里深究,但只是觉得,领导犯下的错,只有我们普通员工来承担。

[联想不是家]

  这是我亲历这两次重大战略调整,所得出的结论。我想,我比许多人都体会深刻。员工和公司的关系,就是利益关系,千万不要把公司当作家。

  当然,这不是说我工作会偷懒。我仍然会好好工作,我要对得起联想。同时,我也觉得联想没有欠我的。联想给了我这么好的工作环境,这么好的学习机会,还有不错的待遇。但,公司就是公司,公司为我做的这一切,都是因为我能为公司做贡献,绝对不是像爸爸妈妈的那种无私奉献的感情。认识到这一点,当我将来离开时,领导会肯定我的业绩,我也会对领导说谢谢,不再会感伤。

  杨元庆说,希望这一次调整给联想带来10年的好运气,但回想上一次战略调整,也就是在2001年11月1日,不禁让人对这句话产生怀疑。怀疑归怀疑,事情还是要做的。生活还要继续。

  ----怀念和我一起共事的众多同事们!

Posted in 转载 | Tagged , , , , , , | Leave a comment

Windows|实现端口转发


所谓端口转发就是A可以访问B,B可以访问C,但是A不能访问C,让A可以通过B间接实现访问C的办法.在Linux下面,可以直接用ssh隧道实现.这里说的是Windows下的实现方法.
现在是2020年,我用的Windows Server 2019.据说2018也可以,不深究了.
用到的命令是:netsh
操作的地点是:B

添加转发

假设C上面开启了22端口,在B上添加2222转发到C的22

netsh interface portproxy add v4tov4 listenaddress=B listenport=2222 connectaddress=C connectport=22

参数释义
listenaddress -- 等待连接的本地ip地址
listenport -- 本地监听的TCP端口(待转发)
connectaddress -- 被转发端口的本地或者远程主机的ip地址
connectport -- 被转发的端口

此时A通过连接B的2222端口,实际上连接的就是C的22

查看转发

如果没有添加前执行下面的命令结果为空

netsh interface portproxy show  v4tov4

删除转发

有始有终是好习惯

netsh interface portproxy delete v4tov4 listenaddress=B listenport=2222

当然linux下也有个叫rinetd的神器,专业端口转发

转载请注明: 转自Rainbird的个人博客
   本文链接: Windows|实现端口转发

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

微信订阅号个人主证成功!


早就听说微信公众号的个人订阅号有人受到邀请开通了个人认证
终于7.1下午,我也收到了官方邀请

关于个人认证开启申请的通知
微信公众号开启新的认证方式,面向个人类型公众号,需申请并进行审核。
审核成功后,搜索公众号会展示认证标识、且“公众号信息-关于公众号页”会展示认证标识及认证信息。申请免费,欢迎体验!
可通过“公众号设置-个人认证-申请认证”发起申请,或点此申请。

收到时间是:17:52

个人认证 - 审核中
根据资料核实难易程度,审核约需要1-3个工作日。审核期间,请留意消息通知,我们可能会下发补充资料的通知,需要你协助补充资料。
第三方审核机构:成都知道创宇信息技术有限公司

收到时间是:17:59

立马按链接提交了个人称呼:雨鸟飞行 与公众号名称一致.
但第二项让填写领域及头衔.
领域要求某某专家之类的,头衔倒是简单直接写了公司名和职位,然后就提交了.

19:16收到四川成都的座机号电话,说是公众号认证事宜,名字没有问题,如果写了头衔,公众号会显示相关真实信息,问是否合理.我说可以隐藏吗?对方说可以写博客内容相关的东西.对方就顺手帮我改成了.

专注于Python开发语言及运维软件知识分享。

19:49收到认证成功消息

个人认证 - 认证成功
恭喜你,你的帐号已于2020-07-01通过个人认证审核。

认证效率很高
感谢

Posted in 原创 | Tagged , , , , | Leave a comment

Python|3.8.3调用阿里云slb的SDK报错两则


域名证书到期,用的阿里云七层SLB,证书也放在了SLB上,乖乖,三十多个SLB要统一更新一下证书,人工操作,容易出错不错,也比较耗时.决定使用阿里云的Python SDK
类似

from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.request import CommonRequest
client = AcsClient('<accessKeyId>', '<accessSecret>', 'cn-hangzhou')
...
...
response = client.do_action_with_exception(request)
# python2:  print(response) 
print(str(response, encoding = 'utf-8'))

拿到示例代码后,直接运行,报错

ModuleNotFoundError: No module named 'aliyunsdkcore'

解决

aliyun-python-sdk-core-v3

再次运行,提示

ModuleNotFoundError: No module named 'aliyunsdkslb'

解决

aliyun-python-sdk-slb

再次运行
提示''和''未设置,这个简单阿里云 后台取一下就可以了
然后就可以愉快的玩耍了.

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

python|GMT时间格式转化(转)


近期域名证书到期了,写了一个Python脚本批量检查,发现证书的时间是GTM格式的,网上找到这篇文章,够用,顺道转了.

datetime类型转换成GMT时间格式

字符串(如'Thu, 19 Feb 2009 16:00:07 GMT'),
strftime(官方释义:new string) :

from datetime import datetime
GMT_FORMAT = '%a, %d %b %Y %H:%M:%S GMT+0800 (CST)'

print(datetime.utcnow().strftime(GMT_FORMAT))

output:

Mon, 12 Nov 2018 08:53:51 GMT+0800 (CST)

将GMT时间格式的字符串转换成datetime类型

strptime(官方释义:new datetime parsed from a string):

dd = "Fri Nov 09 2018 14:41:35 GMT+0800 (CST)"
GMT_FORMAT = '%a %b %d %Y %H:%M:%S GMT+0800 (CST)'
print(datetime.strptime(dd, GMT_FORMAT))

output:

2018-11-09 14:41:35

注意:GMT_FORMAT的格式要与索要转化的字符串相对应。

扩展:python的格式转化

%a 本地的星期缩写
%A 本地的星期全称
%b 本地的月份缩写
%B 本地的月份全称
%c 本地的合适的日期和时间表示形式
%d 月份中的第几天,类型为decimal number(10进制数字),范围[01,31]
%f 微秒,类型为decimal number,范围[0,999999],Python 2.6新增
%H 小时(24进制),类型为decimal number,范围[00,23]
%I 小时(12进制),类型为decimal number,范围[01,12]
%j 一年中的第几天,类型为decimal number,范围[001,366]
%m 月份,类型为decimal number,范围[01,12]
%M 分钟,类型为decimal number,范围[00,59]
%p 本地的上午或下午的表示(AM或PM),只当设置为%I(12进制)时才有效
%S 秒钟,类型为decimal number,范围[00,61](60和61是为了处理闰秒)
%U 一年中的第几周(以星期日为一周的开始),类型为decimal number,范围[00,53]。在度过新年时,直到一周的全部7天都在该年中时,才计算为第0周。只当指定了年份才有效。
%w 星期,类型为decimal number,范围[0,6],0为星期日
%W 一年中的第几周(以星期一为一周的开始),类型为decimal number,范围[00,53]。在度过新年时,直到一周的全部7天都在该年中时,才计算为第0周。只当指定了年份才有效。
%x 本地的合适的日期表示形式
%X 本地的合适的时间表示形式
%y 去掉世纪的年份数,类型为decimal number,范围[00,99]
%Y 带有世纪的年份数,类型为decimal number
%Z 时区名字(不存在时区时为空)
%% 代表转义的"%"字符

————————————————
版权声明:本文为CSDN博主「怠惰的小小白」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_35462323/java/article/details/83994563

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

ELK|Could not retrieve remote IP address for beats input.

ELK日志采集错误一例

背景

公司的ELK系统搭建在阿里云VPC,当然开发环境与生产环境是在两个地域隔离的.正常情况下,每个地域都是独立完整的环境.疫情期间为了节省一些资源,拿掉了开发环境的ELK,直接将日志打到生产的ELK集群
运行了三四个月一直挺正常,可是近来有同事反映,有日志查询不到,但是看日志确实又有其它的日志正常写入.看logstash的日志提示:

[2020-06-15T16:02:09,880][WARN ][logstash.inputs.beats    ] Could not retrieve remote IP address for beats input.
[2020-06-15T16:02:09,880][WARN ][logstash.inputs.beats    ] Could not retrieve remote IP address for beats input.
[2020-06-15T16:02:09,881][WARN ][logstash.inputs.beats    ] Could not retrieve remote IP address for beats input.
[2020-06-15T16:02:09,881][WARN ][logstash.inputs.beats    ] Could not retrieve remote IP address for beats input.
[2020-06-15T16:02:09,881][WARN ][logstash.inputs.beats    ] Could not retrieve remote IP address for beats input.

搜索

拿着Could not retrieve remote IP address for beats input.的错误,去网上搜索,同样的报错很多,官方论坛上也有看似很靠谱的解决方案

https://discuss.elastic.co/t/could-not-retrieve-remote-ip-address-for-beats-input/104815/6

就是改掉代码去掉这个报错!!!
操作

vi /path_to_logstash/vendor/bundle/jruby/2.3.0/gems/logstash-input-beats-5.0.2-java/lib/logstash/inputs/beats/message_listener.rb

      begin
        hash.get("@metadata").put("ip_address", ctx.channel().remoteAddress().getAddress().getHostAddress())
      rescue #should never happen, but don't allow an error here to stop beats input
        input.logger.warn("Could not retrieve remote IP address for beats input.")
      end 


直接注释掉
如上图.
然后重启logstash.
正常按理说,到这里,错误注释掉了,代码继续执行,应该解决问题了.但是,很快有了新的转机.

真凶

正巧,另个同事过来找我说,在测试环境发送邮件,正文很正常,带附件就发送失败.因为对方是用Java程序写的,本能觉得应该他Java玩的不溜,语法问题.
用Python,写了一个发现,同样的正文和附件,本机很快,到了开发环境就不行.看来是网络问题
登陆阿里云,找到VPC的出口网关,乖乖竟然限制了最大出口流量2M.先放开到20M再说
如上图,发现出口流量顶峰竟然跑到了14M.

后话

后续几天一直在观察,发现流量顶多也就跑到3M,看来之前是限制的太死了,日志一直没出去,才造成了大量的积压.有节约的想法是好事儿,应该再向前一步,加个监控,这样才能及时感知变化.

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