• redis 学习


    本篇已收录至redis in action 学习笔记系列

    将系统中的所有程序的配置信息都存储到 redis 当中, 需要获取的时候直接从 redis 中获取, 是否是一个好注意呢?

    情景设计

    公司的系统由于发版, 需要暂时停止服务一段时间, 这段时间如果有用户访问系统, 则需要得到一个 系统正在维护 的消息. 并且当用户不耐其烦的疯狂刷新系统 UI, 尝试访问时, 系统应该对此情况予以考虑设计应对的情况.

    在 redis server中存储一个key为表示系统是否正在维护, 当用户请求系统资源时, 会通过此函数的返回值判断系统当前状态. 并且加了一个 1秒 的请求限制.

    在分布式系统架构中将配置信息放到一个共享访问的地方的威力

    建立一个 redis server 作为配置信息 server?

    设计一个set config函数:

    def set_config(conn, type, component, config):
        conn.set(
            'config:%s:%s'%(type, component),
            json.dumps(config))
    

    还有 get config:

    使用python的装饰器设计一个自动连接redis server管理机制

    上面的code里面无论是 set_config 还是 get_config, 参数都有一个 conn. 这就意味着调用 xx_config 的调用者必须先将对应的 server 连接上得到一个 conn.

    redis自动连接装饰器:

    REDIS_CONNECTIONS = {}
    
    def redis_connection(component, wait=1):
        key = 'config:redis:' + component
        def wrapper(function):
            def call(*args, **kwargs):
                old_config = CONFIGS.get(key, object())
                config = get_config(
                    config_connection, 'redis', component, wait)
    
                if config != old_config:
                    REDIS_CONNECTIONS[key] = redis.Redis(**config)
    
                return function(
                    REDIS_CONNECTIONS.get(key), *args, **kwargs)
            return call
        return wrapper 
    

    代码解析:

    • 有个函数叫 redis_connection
    • 参数 component, type 应为 string, 会通过它拼接出 key 值.
    • 定义了一个内部嵌套函数, wrapper, 参数为 function, 跳过.
    • return wrapper , redis_connection 的返回值是 需要执行 wrapper 函数, 得到 wrapper 函数的返回值返回.
    • 进入wrapper
    • 定义了一个内部嵌套函数, call, 参数为默认参数形式, *args, **kwargs, 继续跳过
    • return call, 此处调用 call, 并将其返回值返回.
    • 进入call
    • 获取旧的config 连接串, 获取新的config连接串, 旧的和新的对比, 如果不相等, 则更新 REDIS_CONNECTIONS 中的值
    • 否则执行 function(REDIS_CONNECTIONS.get(key), *args, **kwargs), function 是一个函数, 第一个参数是 REDIS_CONNECTIONS.get(key) 即 conn, 后面的参数爱是啥是啥
    • call 的返回值是 function 执行过后的返回值
    • wrapper 的返回值是 call 返回的值
    • redis_connection 的返回值是 wrapper 的返回值
    • 解析完毕.

    举例使用:

    @redis_connection('logs')                   #A
    def log_recent(conn, name, message, severity=logging.INFO, pipe=None):
        severity = str(SEVERITY.get(severity, severity)).lower()    #B
        destination = 'recent:%s:%s'%(name, severity)               #C
        message = time.asctime() + ' ' + message                    #D
        pipe = pipe or conn.pipeline()                              #E
        pipe.lpush(destination, message)                            #F
        pipe.ltrim(destination, 0, 99)                              #G
        pipe.execute()                                              #H
    
    log_recent('main', 'User 235 logged in')    #C
    

    装饰器的优点在于调用方法的使用者不必考虑连接 server 的问题.

  • 相关阅读:
    2020全球C++及系统软件技术大会成功落下帷幕
    人工智能能力提升指导总结
    ABAP FUNCTION GUI_DOWN实际应用
    MySQL 数据库基础(二)(MySQL 服务基础与使用 MySQL 数据库)
    【推荐】开源项目ElasticAmbari助力 ElasticSearch、Kibana、ambari服务高效运维管理
    使用navicat连接oracle数据库遇到问题及解决方法
    cv::mat 保存sqlite数据库,使用qt
    工作总结:涉及数据库、软件测试等内容
    数据结构---归并排序
    C语言运算符优先级 详细列表
  • 原文地址:https://www.cnblogs.com/it-dennis/p/12575875.html
Copyright © 2020-2023  润新知