一个结束和开始

来到新加坡SeaGroup 工作基本用了两个月,虽然时间比较短,但是可圈点的东西,还是很多。

一、人

这里的人工作很Nice, 模式很简单。基本对你的需求有求必应。有这样一帮小伙伴在一起工作,是很开心的。 还是要感谢很多人,感谢很多帮助过我的人。Kelvin,简称Angk, 不但技术好,人非常Nice. 他给我印象深刻的有以下:
  1. 技术能力过关(只要有技术问题,我一般都会问他,基本上在Django\Data 方面,没有他解决不了的事)
  2. 文档能力优秀。(在工程师里面,我感觉他是文档能力最好的,文档不但写的条理清楚,而且很易读)。一般工程师都喜欢写代码,不喜欢写文档。像这样全面的人,真是公司的财富。同时,也是我日后的榜样。
  3. 为人。人很简单,很热心。我问他几个问题,有时候只是随口一问。他从来不会忘记,不但当时给我详细的解说,事后,还会写出详细的代码样例,帮助我理解。这样的做事风格和态度,也是我在国内的程序员里很难见到的。
以上这三点,我除了文档写得好一些外,其它都做得不好,又是特别想做好的。特别是第三点,日后也一定要这样的为同事打交道,给他们完整的信息和帮助。

二、技术

这两个月,由于掌握的信息有限,所以对公司的业务上写的东西帮助并不大。可以从后面开发上面,我自己倒是学得了很多,
  1. 写Entry Task,再一次熟悉了Django 框架。对Python后端开发的熟悉程序提高很多。特别是软件应用:Cache Redis应用、MessageQueue应用、InfluxDB\Promethus DB 应用\ DB Model 读写分层处理。
  2. Alert Rule Engine。 这里一个从InfluxDb里拿到报警数据然后做Aggregation的一个小程序。这个项目,我做了有三个多星期,从构思、到实现、基本上是一个人完成。也写了较为详细的文档和计划(Basic filter, Standard filter, 和AI filter)一共是这三步,目前也只实现了Baisc 里面的最基本的 CPU/Memory/Disk/Network 这些基本的监控的聚合。 这个应用是我想了很久的程序。没想到,来到了Shopee两个来月,虽然也实现一点点想法。进入下一家公司也可以继续使用。
  3. CMDB。在临行,就开始考虑拉下来公司的基础架构的事了。我首先想到的是CMDB。这样的一个小系统,虽然实现起来,并不是很样的困难,但是很多公司一开始都重视不够,导致系统大了之后,造成很大的运维的困难。造成的困难很多,也很关键。比如: 自动化部署、自动化监控、报告等。这是运维的基础,应该首先建好。一个好的CMDB, 不管是人维护还是机器维护,首先可保持精准、稳定、易用性。(性能、扩展、等,都不是在一开始要考虑进来的事)
在完成以上任务的同时,我又不得不考虑另外一个重要因素 — 基础算法。在很久时间,我都忽略了这种东西重要性,以至于很晚的今天才接意识到。在考虑Alert Rule Engine 和CMDB的时候,我发现,当要自己设计一个系统时,如何准确、高效的处理数据,是最最关键的部分。花了一个来星期时间,我了解到OOP Pattern Design、了到 Insertion Sort、Binary Search Tree、Linked List 等算法实现。这些都给我了很大的启发。

三、事与态度

 在临走之前,在熟悉了一点点业务的同时,也做出来一点CMDB的Schema,还是有些欣慰的。时间并没有白白费掉。另外,我感觉到了懂得原理的重要性。一个合格的工程师,是会把很多技术工具模型熟念于心的。在使用工具的同时,要做到
  1. 要使懂得工具内部如何实现;
  2. 要懂得如何恰当的使用轮子;
  3. 要懂得如何创造自己的轮子。不可完全依赖它人的算法、逻辑。(很多时候,必要要学会如何创造出合适自己的轮子来。)
先说这样说吧,以上三点,就是这两个多月来,我最大的收获。这些宝贵的东西,将在我接下来的职业生涯乃至人生里面,都会默默的产生力量。我希望可以一以贯之、使自己的认识和能力更可精进一步。
2018.5.18

技术诚可贵,生命价更高

技术值钱。因为,时间宝贵,生命宝贵。
一个小小的技术细节,如果不理解,不懂得,就会让人花了个把个小时去攻破。在个解决问题的过程之中,自己完全忽略外界,整个人被占有。一旦问题解决,自己马上就释放出来。这些宝贵的时间,就在一点一滴中度过了。
不但时间花费过去,整个人的健康也在其中被消耗掉了。干技术的,一旦技术一更新,又得撅着屁股学新的,学习的代价昂贵,耗费精力之大,所以不得不说,技术值钱,是有道理的。
然而,有没有更好的体现值钱的方法?
技术做得再好,代码写得再好,依然不能替代生活,怎么可以忘记,生活才是人生的主线?
技术付钱,生命更值钱。用有限的生命,去换取一朝一夕的技术,大体上,是不值得的。以此谋生,非要懂得平衡付出和收获不可。
话说回来,即使享受着深入练习、深入思考的快感,过去沉迷也是不好的。
所以,也要在方式、方法上多加分析。
  1. 磨刀不误砍柴工,善用工具。光用苦力,在技术上是无意义的。
  2. 少写,多思考,考虑得差不多了之后再写。多收集经验、有没有成熟模型?有没有同样的人遇到同样的问题?文档是怎么写的。这些都要考虑清楚。
  3. 遇到问题,不做过多纠结。超过1小时以上没有解决,一定是自己的方式错误。要先停下来,和练琴一样。
  4. 写东西之前,先列一个框架。写越大的项目,就越是需要架构能力和框架能力。有了架构,才有了方向。列好之后,分段、分时间解决。例如,有几个核心模块?又有多少子模块?每次的模块花久写?Priority 是什么?每个模块花多少时间?
  5. 要时刻关注原理,而不是表象的功能。
  6. 慢下来,不要急
以点,在解决技术问题时要时刻谨记。

Python 非常奇怪的代码现象

  1. #!/usr/bin/python
    
    
    import os
    from subprocess import *
    import sys
    
    import yaml
    def local_run(cmd):
        if cmd:
            p = Popen(cmd, shell=True, stdout=PIPE,stderr=PIPE)
            out,err = p.communicate()
        return(p.returncode, out, err)
    
    
    if __name__ == '__main__':
        rst = local_run("salt 'dev*' state.apply test  --out=yaml")
        data=yaml.load(rst[1])
        if rst[0] == 0:
            print([ data[k][cmd]['result'] for cmd in data[k].keys() for k in data.keys() ])
            print([ [data[k][cmd]['result'] for cmd in data[k].keys() ] for k in data.keys() ])
            # method 1
            #for k in data.keys():
            #    for cmd in data[k].keys():
            #        print data[k][cmd]['result']
            # method 2
        else:
            print rst[2]
            [ data[k][cmd]['result'] for cmd in data[k].keys() for k in data.keys() ]
            sys.exit(rst[0])
    
    

    Traceback (most recent call last):

      File “test.py”, line 20, in <module>

        print([ data[k][cmd][‘result’] for cmd in data[k].keys() for k in data.keys() ])

    NameError: name ‘k’ is not defined

    2. 将两个Expression 对掉,却能生效

    #!/usr/bin/python
    
    
    import os
    from subprocess import *
    import sys
    
    import yaml
    def local_run(cmd):
        if cmd:
            p = Popen(cmd, shell=True, stdout=PIPE,stderr=PIPE)
            out,err = p.communicate()
        return(p.returncode, out, err)
    
    
    if __name__ == '__main__':
        rst = local_run("salt 'dev*' state.apply test  --out=yaml")
        data=yaml.load(rst[1])
        if rst[0] == 0:
            print([ [data[k][cmd]['result'] for cmd in data[k].keys() ] for k in data.keys() ])
            print([ data[k][cmd]['result'] for cmd in data[k].keys() for k in data.keys() ])
            # method 1
            #for k in data.keys():
            #    for cmd in data[k].keys():
            #        print data[k][cmd]['result']
            # method 2
        else:
            print rst[2]
            [ data[k][cmd]['result'] for cmd in data[k].keys() for k in data.keys() ]
            sys.exit(rst[0])

    [[True], [True]]

    [True, True]

    奇怪。

Saltstack Set Roles with Pillar

Saltstack Set Roles with Pillar

Sometimes, we would like to set roles for our servers. This is can be done to define  /srv/pillar/top.sls.

for example

we have:

web_prod01

web_prod02

web_prod02

PART 1 working with pillar

  1. then we can define like this:
base:
   'web_prod*'
       - prod_role

 

2. and in the /srv/pillar/prod_role.sls

role: webserver

3. refresh the pillar file to all matched web_prod*minions

salt “web_prod*” saltutil.refresh_pillar

4. then test it

salt -I ‘role:webserver’ test.ping

additional we can set matched in state file:

base:
 'role:webserver':
   - match: pillar
   - state
   - state2

Reference links:

PART 2 another workaround with external nodegroups

include files in /etc/salt/master

# Include config from several files and directories:

include:

   – /opt/test/saltmgt/nodegroups.yaml

2. cat /opt/test/saltmgt/nodegroups.yaml

nodegroups:

   test1:

     – ‘*prod*’

 

more useful: