• linux端口使用权限

    在Linux系统中,监听1024以下端口需要root权限。因此,如果想监听80,需要使用sudo命令启动程序。 * 示例

    [wyq@localhost ~]$ python -m SimpleHTTPServer 80
    Traceback (most recent call last):
      File "/usr/lib64/python2.7/runpy.py", line 162, in _run_module_as_main
        "__main__", fname, loader, pkg_name)
      File "/usr/lib64/python2.7/runpy.py", line 72, in _run_code
        exec code in run_globals
      File "/usr/lib64/python2.7/SimpleHTTPServer.py", line 220, in <module>
        test()
      File "/usr/lib64/python2.7/SimpleHTTPServer.py", line 216, in test
        BaseHTTPServer.test(HandlerClass, ServerClass)
      File "/usr/lib64/python2.7/BaseHTTPServer.py", line 595, in test
        httpd = ServerClass(server_address, HandlerClass)
      File "/usr/lib64/python2.7/SocketServer.py", line 419, in __init__
        self.server_bind()
      File "/usr/lib64/python2.7/BaseHTTPServer.py", line 108, in server_bind
        SocketServer.TCPServer.server_bind(self)
      File "/usr/lib64/python2.7/SocketServer.py", line 430, in server_bind
        self.socket.bind(self.server_address)
      File "/usr/lib64/python2.7/socket.py", line 224, in meth
        return getattr(self._sock,name)(*args)
    socket.error: [Errno 13] Permission denied
    
  • invalid request block size: 21573 (max 4096)...skip错误原因

    有如下测试代码 test.py

    #!/usr/bin/python
    
    def application(env, start_response):
        start_response('200 OK', [('Content_Type', 'text/html')])
        return "Congraduation!!! uWSGI Testing OK!!!"
    
    • 以uwsgi方式启动
    uwsgi -s :8080 --wsgi-file test.py -M -p 20
    
    • 访问
      在浏览器输入http://0.0.0.0:8080/ 浏览器提示"未收到数据",后台出现错误提示
    invalid request block size: 21573 (max 4096)...skip
    
    • 错误原因
      usgi参数-s表示以socket方式提供通信端口,默认的协议是tcp.
      通过浏览器访问使用的协议是http.

    • 正确方式

    ** 直接提供http服务

    uwsgi --http :8080 --wsgi-file test.py -M -p 20
    

    ** ngix+uwsgi 通过nginx访问uwsgi,uwsgi则可使用以下方式启动

    uwsgi -s :8080 --wsgi-file test.py -M -p 20
    
  • 由于帐户限制,您无法登录

    远程登陆没有密码的windows系统,出现“由于帐户限制,您无法登录”

    解决办法
    * 进入本地安全策略:
    cmd里运行secpol.msc

    • 禁用服务
      本地安全策略 --> 安全选项 -->账户:使用空密码的本地账户只允许进行控制台登陆
  • fedora中iptables与firewall的关系

    fedora上有两个防火墙iptables和firewall.

    它们间的关系

    iptables用于过滤数据包,属于网络层防火墙.
    firewall能够允许哪些服务可用,那些端口可用.... 属于更高一层的防火墙。

    firewall的底层是使用iptables进行数据过滤,建立在iptables之上。

    默认的iptables配置

    [wyq@localhost ~]$ sudo iptables -L -n
    Chain INPUT (policy ACCEPT)
    target     prot opt source               destination         
    
    Chain FORWARD (policy ACCEPT)
    target     prot opt source               destination         
    
    Chain OUTPUT (policy ACCEPT)
    target     prot opt source               destination
    

    firewall启动后,查看iptables的配置
    可以看到,firewall修改了iptables中链路

    [wyq@localhost sysconfig]$ sudo iptables -L -n
    Chain INPUT (policy ACCEPT)
    target     prot opt source               destination         
    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0          
    INPUT_direct  all  --  0.0.0.0/0            0.0.0.0/0          
    INPUT_ZONES_SOURCE  all  --  0.0.0.0/0            0.0.0.0/0          
    INPUT_ZONES  all  --  0.0.0.0/0            0.0.0.0/0          
    ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0          
    REJECT     all  --  0.0.0.0/0            0.0.0.0/0            reject-with icmp-host-prohibited
    
    Chain FORWARD (policy ACCEPT)
    target     prot opt source               destination         
    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
    
    ...........
    
    

    firewall可以提供高层的防火墙。

    所以fedora系统中的设置防火墙,最好使用firewall

  • iptables用法

    iptables过滤网络包. 属于网络层防火墙.

    命令行设置

    • 启用端口
    iptables -A INPUT -p tcp --dport 8000 -j ACCEPT
    
    • 保存配置
    sudo serivce iptables save
    
    • 重启iptables,使配置生效
    sudo serivce iptables restart
    

    配置文件

    永久生效 修改/etc/sysconfig/iptables文件

    -A INPUT -p tcp --dport 8080 -j ACCEPT
    

    注意要加在最后一个COMMIT前

    否则会出现错误

    Redirecting to /bin/systemctl restart  iptables.service
    Job for iptables.service failed. See 'systemctl status iptables.service' and 'journalctl -xn' for details.
    

    基本用法

    查看本机iptables设置

    iptables -L -n
    
    • 启用端口
    iptables -A INPUT -p tcp --dport 8000 -j ACCEPT
    
    • 禁用端口
    iptables -A INPUT -p tcp --dport 8000 -j REJECT
    
    • 清除规则 iptables -F 清除filter中的所有规则链的规则 iptables -X 清除filter中使用者自定链中的规则
  • fedora的firewall配置

    iptables可以过滤数据包,属于网络层的防火墙。fedora中还有一层防火墙软件firewall。属于更高一层的防火墙,并且是动态防火墙,修改配置后,会自动生效,不需要重启。
    可以控制服务,控制端口,设置安全区域,设置端口转发等功能。

    配置工具

    1. firewall-config 图形配置界面
    2. firewall-cmd 命令行配置

    firewall-cmd用法 * 启用端口

    firewall-cmd [--zone=<zone>] --add-port=<port>[-<port>]/<protocol> [--timeout=<seconds>]
    

    示例

    firewall-cmd --add-port=8080/tcp
    
    • 禁用端口
    firewall-cmd [--zone=<zone>] --remove-port=<port>[-<port>]/<protocol>
    

    示例

    firewall-cmd --remove-port=8080/tcp
    
    • 启用服务
    firewall-cmd [--zone=<zone>] --add-service=<service> [--timeout=<seconds>]
    

    示例

    firewall-cmd --add-service=http
    
    • 禁用服务
    firewall-cmd [--zone=<zone>] --remove-service=<service>
    

    示例

    firewall-cmd --zone=home --remove-service=http
    

    上面是临时配置,系统重启后会失效。
    如果加上参数--permanent,就会永久配置,重启后依然有效。

  • meliae内存分析-基本用法

    python的内存分析工具meliae,挺好用的.

    示例

    1. 记录程序的内存使用信息
    import time
    
    # 此处是可能发生内存泄露的地方
    def main():
        pass
    
    if __name__ == '__main__':
        # 通过循环执行,将泄露的内存积累放大
        while True:
            main()
            time.sleep(10)
            # 记录每次执行完后占用的内存
            from meliae import scanner
            scanner.dump_all_objects('mem_dump%s' % time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
    
    1. 查看占用的内存大小
    from meliae import loader
    om = loader.load('mem_dump2014-02-2022-34-43')
    om.summarize()
    

    具体分析引用关系太麻烦,以上是个人喜欢的方法:
    用循环将泄露的内存累积放大. 然后记录每次执行完后占用的内存.
    查看占用内存大小. 再比较每次的内存大小,即可知道是否发生泄露.
    至于内存泄露的地方,则用排除法,重复上述过程,定位泄露地点.

    基本用法

    获取进程的内存信息

    import time
    from meliae import scanner
    scanner.dump_all_objects('mem_dump%s' % time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
    
    • 查看占用内存
    from meliae import loader
    #加载dump文件
    om = loader.load('mem_dump2014-02-2022-34-43')
    #分析内存占用情况
    om.summarize()
    
    • 输出样例
    Total 40335 objects, 125 types, Total size = 6.5MiB (6768944 bytes)
     Index   Count   %      Size   % Cum     Max Kind
         0    1245   3   1792824  26  26   98584 dict
         1   18560  46   1568824  23  49   12479 str
         2     226   0    730272  10  60   12624 module
         3     559   1    505336   7  67     904 type
         4    3573   8    457344   6  74     128 code
         5    3759   9    451080   6  81     120 function
         6    2506   6    189840   2  84     576 tuple
         7    1383   3    163768   2  86    4280 list
         8    1303   3    104240   1  88      80 wrapper_descriptor
         9     895   2     78760   1  89      88 weakref
        10     942   2     67824   1  90      72 builtin_function_or_method
        11     198   0     66928   0  91    8424 set
        12     388   0     65136   0  92    1552 unicode
        13     807   2     58104   0  93      72 method_descriptor
        14      50   0     56000   0  93    1120 OracleDB
        15    1680   4     40320   0  94      24 int
        16      36   0     36768   0  95    1192 StgDict
        17     446   1     32112   0  95      72 getset_descriptor
        18      87   0     29928   0  95     344 WeakSet
        19     395   0     28440   0  96      72 member_descriptor
    

    字段说明
    * Index : 行索引号
    * Count : 该类型的对象总数
    * %(Count) : 该类型的对象总数 占 所有类型的对象总数 的百分比
    * Size : 该类型的对象总字节数
    * %(Size) : 该类型的对象总字节数 占 所有类型的对象总字节数 的百分比
    * Cum : 累积行索引后的%(Size)
    * Max : 该类型的对象中,最大者的字节数
    * Kind : 类型

    • 对象及引用关系
      个人不喜欢用这个
    #得到所有的OracleDB对象
    p = om.get_all('OracleDB')
    #查看第一个对象
    p[0]
    #可以查看该对象的所有引用
    p[0].c
    #查看谁引用了这个对象
    p[0].p
    
  • mongodb安装

    在fedora 20中安装mongodb

    • 安装 bash sudo yum install mongodb mongodb-server

    • 启动服务器 bash sudo service mongod start

    如果以mongod命令启动,要有数据库路径,否则会出现

    ERROR: dbpath (/data/db/) does not exist.
    Create this directory or give existing directory in --dbpath.
    
    • 进入后台管理
    mongo
    

    即可使用脚本管理. 例如: show dbs 查看数据库

    You are trying to access MongoDB on the native driver port. For http diagnostic access, add 1000 to the port number
    

    据提示访问 http://localhost:28017/
    结果访问不了,发现默认限制访问
    修改 /etc/mongodb.conf

    # Disable the HTTP interface (Defaults to port+1000).
    nohttpinterface = true
    

    注释掉再重启,即可访问

    • 使用自己的配置文件
    mongod -f mongodb.conf
    
    • 在命令行中指定数据存放路径
    mongod --dbpath=/opt/mongodb/data
    
    • 停止服务
    sudo service mongod stop
    

    以mongod -f ...启动,也可停止

  • SQL标准规定中null值判断是否合理?

    在postgres中判断null值时,下面语句的结果不相等,为什么?

    select * from user_info where user_name is null
    select * from user_info where user_name = null
    

    原因是postgres遵循sql标准,在ANSI SQL(SQL-92)标准中规定的Null值的比较取值结果都为False.
    它认为NULL 代表一个未知的数值,无法知道两个未知的数值是否相等。

    这个理由很不充分,既然无法判断,那么is null又是如何判断它是空的呢?

    虽然null表面含义是未知值,但是计算机中不可能有不确定的表示. 常见程序语言中null实际都是一个特殊值,一个确定的特殊值。所以在编程语言中是允许使用null=null(值比较)的. SQL中不允许是否合理?

  • postgres递归查询

    示例

    WITH RECURSIVE t AS (
        select * from danger_classify where parent_id = -1
    
        UNION ALL
    
        select dc.* from danger_classify dc, t
        where dc.parent_id = t.id
    )
    SELECT * FROM t;
    

    运行过程 包含recursive的关键字,需要有union或者union all
    1. 计算非递归内容,放入工作表;
    2. 只要工作表不为空计算一下内容:
    1) 计算递归项,用自身的递归取代工作表。去掉重复内容,之前的内容。剩下的内容进行递归,并且放入中间表
    2) 用中间标内容替换工作标,并且清空中间表.

    解析为树形数据

    def get_tree_data():
        sql = '''
            WITH RECURSIVE t AS (
                select * from danger_classify where parent_id = -1
    
                UNION ALL
    
                select dc.* from danger_classify dc, t
                where dc.parent_id = t.id
            )
            SELECT * FROM t;
        '''
        trees = []
        temp = {}
        for row in database.db.query(sql):
            tree = {"id": int(row.id), "data": row, "children": []}
            temp[row.id] = tree["children"]
            if row.parent_id is None:
                trees.append(tree)
            else:
                temp[row.parent_id].append(tree)
        return trees
    

    原理是借用了引用的特性。在temp中平铺所有的节点,在trees中保存结果。在temp中操作来改变trees中的结构,形成树状.