-App后台开发运维和架构实践
        -推荐序
                -十八般兵器入门
        -前言
        -致谢
        -目录
        -第1章 App后台入门
            -1.1 App后台的功能
            -1.2 App后台架构
            -1.3 App和App后台的通信
    -   {
    -       "age": 11,
    -       "name": "jeff"
    -    }
    -书名页
    -   jeff
    -   11
            -1.4 App后台和Web后端的区别
            -1.5 选择服务器
            -1.6 选择编程语言
            -1.7 快速入门新技术
                -1.7.1 思维模式
                -1.7.2 4种快速入门新技术的方法
            -1.8 App是怎样炼成的
                -1.8.1 项目启动阶段
                -1.8.2 研发阶段
                -1.8.3 测试阶段
                -1.8.4 正式推出阶段
            -1.9 最适合App的开发模式——敏捷开发
                -1.9.1 Sprint计划会议
                -1.9.2 日常开发
                -1.9.3 每日例会
                -1.9.4 测试和修复Bug
                -1.9.5 评审会议
                -1.9.6 回顾会议
                -1.9.7 及时反馈
                -1.9.8 总结
        -第2章 App后台基础技术
            -2.1 从App业务逻辑中提炼API接口
                -2.1.1 业务逻辑思维导图
                -2.1.2 功能—业务逻辑思维导图
                -2.1.3 基本功能模块关系
                -2.1.4 功能模块接口UML(设计出API)
                -2.1.5 编写在线API测试文档
                -2.1.6 设计稿标注API
            -2.2 设计API的要点
            -2.3 如何选择合适的数据库产品
                -2.3.1 Redis,MongoDB,MySQL读写数据的区别
                -2.3.2 Redis,MongoDB,MySQL查找数据的区别
                -2.3.3 Redis,MongoDB,MySQL适用场景
            -2.4 如何选择消息队列软件
                -2.4.1 为什么要用消息队列?
                -2.4.2 消息队列的工作流程
                -2.4.3 常见的一些消息队列产品
            -2.5 使用分布式服务实现业务的复用
                -2.5.1 巨无霸系统的危害
                -2.5.2 远程服务的优点
                -2.5.3 远程服务的实现
            -2.6 搜索技术入门
                -2.6.1 一个简单的搜索例子
                -2.6.2 搜索技术的基本原理
                -2.6.3 常见的开源搜索软件介绍
            -2.7 定时任务
                -2.7.1 Linux定时任务Crontab
    -   crontab [-u username] [-l|-e|-r]
    -   参数:
    -   -u :只有 root 才能进行这个任务,编辑某个用户的crontab
    -   -e :编辑 crontab 的工作内容
    -   -l :查阅 crontab 的工作内容
    -   -r :移除所有的 crontab 的工作内容。
    -   * * * * * cmd
    -   * * * * * sleep 20; cmd
    -   * * * * * sleep 40; cmd
                -2.7.2 在后台轻松管理各种各样的定时任务
    -   easy_install apscheduler
    -   Python setup.py install
    -   from datetime import datetime
    -   import time
    -   from apscheduler.scheduler import Scheduler
    -   def tick():
    -       print('Tick! The time is: %s' % datetime.now())
    -   if __name__ == '__main__':     scheduler = Scheduler()
    -       scheduler.add_interval_job(tick, seconds=3)
    -       print('Press Ctrl+C to exit')
    -       scheduler.start()
    -       # This is here to simulate Application activity (which keeps the main thread alive).
    -       while True:
    -           print('This is the main thread.')
    -           time.sleep(2)
        -第3章 App后台核心技术
            -3.1 用户验证方案
                -3.1.1 使用HTTPS协议
                -3.1.2 基本的用户登录方案
            -3.2 App通信安全
                -3.2.1 URL签名
    -   sign=md5("test.com/user/info?token=daf32da456hfdh”)= 6dac4026135a123a3cf809a1f1bf1d2a
    -   test.com/user/info?userId=5&sign= 6dac4026135a123a3cf809a1f1bf1d2a
    -   sign= md5("test.com/user/info?userId=5&token=daf32da456hfdh×tamp= 1425860757")= C116161A6F430343B6CECF08562F1371
    -   test.com/user/info?userId=5×tamp=1425860757&sign=c11616A6F430343B6C ECF08562F1371
                -3.2.2 AES对称加密
    -   AES加密(data, secretKey)
    -   {"userId":5,"name":"jeff","token":"daf32da456hfdh }
    -   {"userId":5,"name":"jeff","token":"daf32da456hfdh }
    -   Token-Param:1425860757
    -   {"userId":5,"name":"jeff","token":"daf32da456hfdh }
    -   {"nickName":"jeff"}
    -   Token-Param:1425860767
    -   Token-Data:Base64Encode(AES加密(token, secretKey))
    -   Base64Encode(AES加密(昵称数据, token))
                -3.2.3 更进一步的通信安全
            -3.3 短信服务
                -3.3.1 App后台发送短信简介
                -3.3.2 选择短信平台
                -3.3.3 建立可靠的短信服务
    -   配置文件App.conf中关于短信平台的配置:
    -   [sms]
    -   currentSmsPlat=短信平台a
    -   /*
    -   * 发送短信的逻辑
    -   */
    -   //读取配置文件中设置使用的短信平台
    -   smsPlat = readConf(“sms: :currentSmsPlat”);
    -   if (smsPlat == “短信平台a”) {  //判断使用哪个短信发送短信
    -       /* 使用短信平台a发送短信 */
    -   } elseif (smsPlat == “短信平台b”) {
    -       /* 使用短信平台b发送短信 */
    -   }
            -3.4 处理表情的一些技巧
                -3.4.1 表情在MySQL的存储
                -3.4.2 当文字中夹带表情的处理
                -3.4.3 Openfire中发送表情引起连接断开的问题
    -   src\Java\org\jivesoftware\Openfire\net\MXParser.Java
    -   protected char more() throws IOException, XMLPullParserException {
    -   final char codePoint = super.more(); // note - this does NOT return a codepoint now, but simply a (single byte) character!
    -       if ((codePoint == 0x0) || // 0x0 is not allowed, but flash clients insist on sending this as the very first character of a stream. We should stop allowing this codepoint after the first byte has been parsed.
    -
    -
    -
    -
    -
    -         ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF)))  {
    -        return codePoint;
    -      }
    -     throw new XMLPullParserException("Illegal XML character: " + Integer. parseInt(codePoint+"", 16));
    -       }
    -   在这段代码把特殊的表情符号值当成了一个异常抛出,所以Openfire会断开连接。
    -   解决方法是把特殊的表情符号值也包含,代码修改如下:
    -       @Override
    -       protected char more() throws IOException, XMLPullParserException {
    -    final char codePoint = super.more(); // note - this does NOT return a codepoint now, but simply a (single byte) character!
    -     if ((codePoint == 0x0) || // 0x0 is not allowed, but flash clients insist on sending this as the very first character of a stream. We should stop allowing this codepoint after the first byte has been parsed.
    -
    -
    -
    -       //fix some emotion
    -
    -       ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF))) {
    -      return codePoint;
    -     }
    -     throw new XMLPullParserException("Illegal XML character: " + Integer. parseInt(codePoint+"", 16));
    -       }
            -3.5 高效更新数据
                -3.5.1 内容的推拉
                -3.5.2 数据增量更新策略
    -   count:每页的显示条数(默认为3)
    -   page:当前页码(默认为1)
    -   since:时间戳,若指定此参数,则返回时间戳大于等于since的结果(应该是上次获取的最新数据的update_time)
    -   max:时间戳,若指定此参数,则返回时间戳少于等于max的结果(应该是发送时的时间)
    -   SQL查询时使用条件since<=数据的更新时间<=max
    -       {
    -          "size": 10,   //实际返回的数据量(因为分页获取的缘故,该值经常少于total值)
    -          "total": 284,  //应该返回的总数据量
    -          "page": 1,     //把请求的参数回传
    -          "count": 3, //把请求的参数回传
    -       "max": 0, //max为获取的最后一条数据的update_time
    -       "since": 0,
    -       "data":{ /*返回的数据实体*/ }
    -       }
    -书名页
    -   http://test/api/timeline?count=3&page=1&since=0&max=1105
    -   API返回的数据
    -   {
    -       "size": 3,   //实际返回的数据量
    -       "total": 3,  //应该返回的总数据量
    -       "page": 1,
    -       "count": 3,
    -       "max": 1101,
    -       "since":0,
    -       "data":{ /*返回的数据实体*/ }
    -   }
    -   http://test/api/timeline?count=3&page=1&since=1102&max=1120
    -   API返回的数据
    -   {
    -       "size": 3,   //实际返回的数据量(因为分页获取的缘故,所以经常少于total值)
    -       "total": 4,  //应该返回的总数据量
    -       "page": 1,
    -       "count": 3,
    -       "max": 1119,
    -       "since":1102,
    -       "data":{ /*返回的数据实体*/ }
    -   }
    -   http://test/api/timeline?count=3&page=1&since=1119&max=1120
    -   API返回的数据
    -   {
    -       "size": 2,   //实际返回的数据量(因为分页获取的缘故,所以经常少于total值)
    -       "total": 2,  //应该返回的总数据量
    -       "page": 1,
    -       "count": 3,
    -       "max": 1119,
    -       "since":1119,
    -       "data":{ /*返回的数据实体*/ }
    -   }
            -3.6 图片处理
            -3.7 视频处理
                -3.7.1 FFmpeg简介
                -3.7.2 后台调用FFmpeg的功能
    -   ffmpeg -i source.avi -f psp -r 29.97 -b 768k -ar 24000 -ab
    -   64k -s 320×240 destination.mp4
    -   File source = new File("source.avi");
    -   File target = new File("target.flv");
    -   AudioAttributes audio = new AudioAttributes();
    -   audio.setCodec("libmp3lame");
    -   audio.setBitRate(new Integer(64000));
    -   audio.setChannels(new Integer(1));
    -   audio.setSamplingRate(new Integer(22050));
    -   VideoAttributes video = new VideoAttributes();
    -   video.setCodec("flv");
    -   video.setBitRate(new Integer(160000));
    -   video.setFrameRate(new Integer(15));
    -   video.setSize(new VideoSize(400, 300));
    -   EncodingAttributes attrs = new EncodingAttributes();
    -   attrs.setFormat("flv");
    -   attrs.setAudioAttributes(audio);
    -   attrs.setVideoAttributes(video);
    -   Encoder encoder = new Encoder();
    -   encoder.encode(source, target, attrs);
            -3.8 获取APK和IPA文件里的资源
                -3.8.1 Android的APK文件
    -   /usr/bin/sudo /usr/local/bin/aapt dump badging apk文件路径
                -3.8.2 iOS的IPA文件
    -   require_once(__DIR__.'/../classes/CFPropertyList/CFPropertyList.PHP');
    -   $content = file_get_contents("/tmp/Info.plist");
    -   $plist = new CFPropertyList();
    -   $plist->parse($content);
    -   var_dump( $plist->toArray() );
    -   array(29) {
    -     'CFBundleName' =>
    -     string(12) "DataDemo"
    -     'DTXcode' =>
    -     string(4) "0511"
    -     'DTSDKName' =>
    -     string(11) "iPhoneos7.1"
    -     'DTSDKBuild' =>
    -     string(6) "11D167"
    -     'CFBundleDevelopmentRegion' =>
    -     string(2) "en"
    -     'CFBundleVersion' =>   //版本号
    -     string(3) "2.0"
    -     .....
    -   ' CFBundleDisplayName ' =>   //应用名称
    -     string(12) "DataDemo"
    -     .........
    -     array(1) {
    -       'CFBundlePrimaryIcon' =>
    -       array(1) {
    -         'CFBundleIconFiles' =>  //图标文件
    -         array(2) {
    -           [0] =>
    -           string(5) "icon2"
    -           [1] =>
    -           string(4) "icon"
    -         }
    -   }
    -   'CFBundleVersion':版本号
    -   'CFBundleDisplayName':应用名称
    -   'CFBundlePrimaryIcon'->'CFBundleIconFiles': 图标文件
    -   require_once 'pngCompote.php';
    -   $filename = 'Lenna.crush.png'; //需要解密的文件路径
    -   $newFilename = 'Lenna.compote.png'; //解密后的文件路径
    -   $png = new PngFile($filename);
    -   if ($png->revertIPhone($newFilename)) {
    -           echo 'cleaning done!'.PHP_EOL;
    -           echo ''.PHP_EOL;
    -   }
            -3.9 文件系统
                -3.9.1 文件云存储服务
                -3.9.2 架设文件系统
            -3.10 ELK日志分析平台
                -3.10.1 基本模块
                -3.10.2 日志分析流程
            -3.11 Docker构建一致的开发环境
                -3.11.1 Docker原理
                -3.11.2 搭建一致的开发环境
    -   # 下载基础镜像
    -   FROM dockerfile/ubuntu
    -   # 安装Java.
    -   Run echo oracle-Java7-installer shared/accepted-oracle-license-v1-1 select true | debconf-set-selections && \
    -     add-apt-Repository -y ppa:Webupd8team/Java && \
    -     apt-get update && \
    -     apt-get install -y oracle-Java7-installer && \
    -     rm -rf /var/lib/apt/lists/* && \
    -     rm -rf /var/cache/oracle-jdk7-installer
    -   # 定义工作目录
    -   WORKDIR /data
    -   # 定义JAVA_HOME环境变量
    -   ENV JAVA_HOME /usr/lib/jvm/java-7-oracle
    -   # 定义默认的命令
    -   CMD ["bash"]
        -第4章 Linux——App后台应用最广泛的系统
            -4.1 基本的系统优化
                -4.1.1 开机自启动服务优化
    -   # Default runlevel. The runlevels used by RHS are:   0 - halt (Do NOT set initdefault to this) ,表示关机
    -   #   1 - Single user mode,单用户模式   2 - Multiuser, without NFS (The same as 3, if you do not have networking),
    -   无网络连接的多用户命令行模式
    -   #   3 - Full multiuser mode,有网络连接的多用户命令行模式   4 – unused,不用
    -   #   5 - X11,带图形界面的多用户模式   6 - reboot (Do NOT set initdefault to this),重新启动
    -   chkconfig [--add][--del][--list][系统服务]
    -   [root@mode ~]# chkconfig --list|grep 3:on
    -   crond           0:off   1:off   2:on    3:on    4:on    5:on    6:off
    -   network         0:off   1:off   2:on    3:on    4:on    5:on    6:off
    -   sshd            0:off   1:off   2:on    3:on    4:on    5:on    6:off
    -   syslog          0:off   1:off   2:on    3:on    4:on    5:on    6:off
    -   chkconfig [--level <等级代号>][系统服务][on/off/reset]
    -   chkconfig --add nginx
    -   chkconfig --level 35 nginx on
                -4.1.2 增大文件描述符
    -   [root@modecron]# ulimit -n
    -   1024
    -   [root@modecron]# ulimit -HSn 65535
    -   [root@modecron]# ulimit -n
    -   65535
    -   在/etc/security/limits.conf中加入
    -   *    -     nofile    65535
    -   [root@mode ~]# sysctl -a|grep file-max
    -   fs.file-max = 1024
    -   sysctl -w fs.file-max=65535
            -4.2 常用的命令
                -4.2.1 全面了解系统资源情况——top
    -   sync&& echo3 >/proc/sys/vm/drop_caches
    -   top -p进程id
                -4.2.2 显示进程状态——ps
    -   ps axu|grep 进程名
    -   ps axu|grep php
                -4.2.3 查看网络相关信息——netstat
    -   -l: listen,监听的端口。
    -   -a: 显示所有的Socket,包括正在监听。
    -   -n:显示数字格式的地址。
    -   -t:监听TCP的端口。
    -   -u:监听UDP的端口。
    -   -p:显示建立相关链接的程序名。
    -   netstat–lntup
    -   netstat–lntup|grep 80
    -   netstat–nat|grep 80
                -4.2.4 查看某个进程打开的所有文件——lsof
    -   -p: 进程的 id
    -   lsof -p 7989
                -4.2.5 跟踪数据到达主机所经路由——traceroute
                -4.2.6 文件下载/上传工具——“ssh secure shell client”和“lrzsz”
    -   yum -y install lrzsz
                -4.2.7 查看程序的依赖库——LD_DEBUG
    -   error while loading shared libraries: xxxx.so.2:
    -   cannot open shared object file: No such file or directory
                -4.2.8 进程管理利器——superivisor
    -   nohupsh /data/sendmail.sh 2>&1 >> /data/logs/sendmail.log &
    -   yum install supervisor
    -   [unix_http_server]
    -   file=/tmp/supervisor.sock ; (the path to the Socket file)
    -   [supervisord]
    -   logfile=/tmp/supervisord.log ; (main log file;default $CWD/supervisord.log)
    -   logfile_maxbytes=50MB     ; (max main logfile bytes b4 rotation;default 50MB)
    -   logfile_backups=10        ; (num of main logfile rotation backups;default 10)
    -   loglevel=info             ; (log level;default info; others: debug,warn,trace)
    -   pidfile=/tmp/supervisord.pid ; (supervisordpidfile;defaultsupervisord.pid)
    -   nodaemon=false            ; (start in foreground if true;default false)
    -   minfds=1024               ; (min. avail startup file descriptors;default 1024)
    -   minprocs=200              ; (min. avail process descriptors;default 200)
    -   [rpcinterface:supervisor]
    -   supervisor.rpcinterface_factory
    -   supervisor.rpcinterface:make_main_rpcinterface
    -   [supervisorctl]
    -   serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix Socket
    -   [include]
    -   files = /etc/supervisord.conf.d/*.conf
    -   [program:mail]                        ; 在supervisor 监控列表中的标识
    -   directory = /data                     ; 启动命令时进入的目录,如果command 中的命令没有使用绝对路径,这项一定要设置
    -   command = /bin/sh /data/sendmail.sh   ; 启动的命令
    -   autostart = true                      ; 随着supervisor 启动而启动。
    -   autoRESTart = true                    ; 自动重启。
    -   startretries = 10                     ; 启动失败时的最多重试次数
    -   startsecs = 5                         ; supervisor 启动5 秒后启动
    -   user = root                           ; 以root 用户的身份运行
    -   redirect_stderr = true                ; 重定向stderr 到stdout
    -   numprocs=1                            ; 启动1 个进程
    -   stdout_logfile = /data/logs/mail.log  ; 输出日志的位置
    -   /usr/bin/Python /usr/bin/supervisord -c /etc/supervisord.conf
    -   supervisorctl status
    -   mail          RUNNING   pid 12663, uptime 0:00:07
    -   [root@ ~]# supervisorctl stop mail
    -   mail: stopped
            -4.3 故障案例分析
        -第5章 Nginx——App后台HTTP服务的利器
            -5.1 简介
            -5.2 基本原理
                -5.2.1 工作模型
                -5.2.2 进程解析
            -5.3 常用配置
                -5.3.1 Nginx的全局配置
    -   user  www www;
    -   worker_processes 4;
    -   error_log  /home/wwwlogs/nginx_error.log  crit;
    -   pid        /usr/local/nginx/logs/nginx.pid;
    -   worker_rlimit_nofile 52000;
                -5.3.2 event配置
    -   events
    -   {
    -   use epoll;
    -   worker_connections 51200;
    -   }
                -5.3.3 http配置
    -   http{
    -   include mime.types;
    -   default_type Application/octet-stream;
    -   client_header_buffer_size 32k;
    -   large_client_header_buffers 4 32k;
    -   client_max_body_size 50m;
    -   sendfile on;
    -   tcp_nopush on;
    -   keepalive_timeout 60;
    -   tcp_nodelay on;
    -   gzip on;
    -   gzip_min_length 1k;
    -   gzip_buffers 4 16k;
    -   gzip_http_version 1.0;
    -   gzip_comp_level 2;
    -   gzip_types text/plain Application/x-javascript text/css Application/xml;
    -   gzip_vary on;
    -   include vhost/*.conf;
    -   }
                -5.3.4 负载均衡配置
    -   upstream test.com{
    -   server 192.168.1.20:80 weight=2;;
    -   server 192.168.1.21:80 weight=1;
    -   }
                -5.3.5 server虚拟主机配置
                -5.3.6 location配置
    -   location ~ .*\.(gif|jpg|jpeg|png)$
    -   {
    -     expires      30d;
    -   }
                -5.3.7 HTTPS的配置
    -   yum install openssl
    -   yum install openssl-devel
    -   cd  /usr/local/nginx/conf
    -   opensslgenrsa -des3 -out local.key 1024
    -   opensslreq -new -key local.key -out local.csr
    -   opensslrsa -in local.key -out local_nopwd.key
    -   openssl x509 -req -days 365 -in local.csr -signkey local_nopwd.key -out local.crt
    -   server {
    -       listen 443;
    -       ssl on;
    -       ssl_certificate  /usr/local/nginx/conf/local.crt;
    -       ssl_certificate_key  /usr/local/nginx/conf/local_nopwd.key;
    -       server_name api.test.cn;
    -       index index.html index.htm index.php default.html default.htm default.php;
    -       root  /var/www/test;
    -   }
                -5.3.8 下载App的配置
    -   application/vnd.android.package-archive apk;
    -   application/iphone pxl ipa;
                -5.3.9 生产环境中修改配置的良好习惯
    -   [root@mode ~]# /usr/local/nginx/sbin/nginx -s reload
            -5.4 性能统计
    -   location /nginx_status {
    -   stub_status on;
    -   access_log   off;
    -   }
    -   Active connections: 1
    -   server accepts handled requests
    -   653 653 685
    -   Reading: 1 Writing: 1 Waiting: 0
    -   上面每项的含义如下。
            -5.5 实现负载均衡的方案
            -5.6 用Nginx处理业务逻辑
    -   location /lua {
    -       set $test "hello, world.";
    -       content_by_lua '
    -           ngx.header.content_type = "text/plain";
    -           ngx.say(ngx.var.test);
    -       ';
    -   }
        -第6章 MySQL——App后台最常用的数据库
            -6.1 基本架构
            -6.2 选择版本
            -6.3 配置文件详解
    -   max_connections = 1000
    -   max_connect_errors = 50
    -   key_buffer_size = 3M
    -   max_allowed_packet = 16M
    -   thread_cache_size = 300
    -   thread_concurrency = 8
    -   sort_buffer_size = 1M
    -   join_buffer_size = 8M
    -   query_cache_size = 512M
    -   query_cache_limit = 2M
    -   read_buffer_size = 2M
    -   read_rnd_buffer_size = 16M
    -   myisam_sort_buffer_size = 8M
    -   innodb_buffer_pool_size = 4G
    -   innodb_log_file_size = 128M
    -   innodb_log_buffer_size = 8M
    -   innodb_flush_log_at_trx_commit = 1
    -   innodb_lock_wait_timeout = 50
            -6.4 软件优化
                -6.4.1 正确使用MyISAM和InnoDB存储引擎
                -6.4.2 正确使用索引
                -6.4.3 避免使用seIect*
                -6.4.4 字段尽可能地设置为NOT NULL
            -6.5 硬件优化
                -6.5.1 增加物理内存
                -6.5.2 增加应用缓存
                -6.5.3 用固态硬盘代替机械硬盘
    -   //这个参数控制了InnoDB 刷新日志和数据的模式,O_DIRECT 是告诉操作系统禁用缓存,然后使用fsync()的方式将数据刷入磁盘。fsync()的方式确保数据已经被记录在硬盘上。
    -   innodb_flush_method=O_DIRECT
    -   //控制MySQL 中一次刷新的脏页的数量,在使用SSD 后其io 能力大大增强,需要增大一次刷新脏页的数量。
    -   innodb_io_capacity=10000
                -6.5.4 SSD硬盘+SATA硬盘混合存储方案
            -6.6 架构优化
                -6.6.1 分表
                -6.6.2 读写分离
                -6.6.3 分库
            -6.7 SQL慢查询分析
    -   set global long_query_time=1;
    -   set global slow_query_log=on;
    -   set global slow_query_log_file='/data/slow.log';
    -   [MySQLd]
    -   long_query_time=1
    -   slow_query_log=ON
    -   slow_query_log_file=/data/slow.log
    -   mysqldumpslow -t 3 /data/slow.log
            -6.8 云数据库简介
            -6.9 灵活的存储结构
            -6.10 故障排除案例
        -第7章 Redis——App后台高性能的缓存系统
            -7.1 Redis简介
            -7.2 Redis的常用数据结构及应用场景
                -7.2.1 string——存储简单的数据
    -   get category
                -7.2.2 hash——存储对象的数据
    -   hgetall id
                -7.2.3 list——模拟队列操作
                -7.2.4 set——无序且不重复的元素集合
                -7.2.5 sorted set——有序且不重复的元素集合
    -   ZADD key score member
    -   127.0.0.1:6379>zadd userTop 112 mike
    -   (integer) 1
    -   127.0.0.1:6379>zadd userTop 111 ekin
    -   (integer) 1
    -   127.0.0.1:6379>zadd userTop 104 terry
    -   (integer) 1
    -   127.0.0.1:6379>zadd userTop 179 jeff
    -   (integer) 1
    -   127.0.0.1:6379>zadd userTop 127 tom
    -   (integer) 1
    -   zrevrange key start stop [withscores]
    -   127.0.0.1:6379>zrevrange userTop 0 -1 WITHSCORES
    -    1) "jeff"
    -    2) "179"
    -    3) "tom"
    -    4) "127"
    -    5) "mike"
    -    6) "112"
    -    7) "ekin"
    -    8) "111"
    -    9) "terry"
    -   10) "104"
            -7.3 内存优化
                -7.3.1 监控内存使用的状况
    -   # Memory
    -   used_memory:12660096
    -   used_memory_human:12.07M
    -   used_memory_rss:14299136
    -   used_memory_peak:15534680
    -   used_memory_peak_human:14.82M
    -   used_memory_lua:31744
    -   mem_fragmentation_ratio:1.13
    -   mem_allocator:jemalloc-3.2.0
                -7.3.2 优化存储结构
    -   hash-max-ziplist-entries 512
    -   hash-max-ziplist-value 64
                -7.3.3 限制使用的最大内存
                -7.3.4 设置过期时间
    -   EXPIRE key seconds
            -7.4 集群
                -7.4.1 客户端分片
                -7.4.2 Twemproxy
                -7.4.3 Codis
                -7.4.4 Redis 3.0集群
                -7.4.5 云服务器上的集群服务
            -7.5 持久化
                -7.5.1 RDB
    -   dbfilename dump.rdb #快照的文件名
    -   dir /var/lib/redis/6379 #快照保存的路径
    -   save 900 1              #当有1 个数据被改变时,900 秒刷新到硬盘一次
    -   save 300 10             #当有10 个数据被改变时,300 秒刷新到硬盘一次
    -   save 60 10000           #当有10000 数据被改变时,60 秒刷新到硬盘一次
                -7.5.2 AOF
    -   Appendonly no                    #是否开启AOF 的持久化方式
    -   Appendfilename "Appendonly.aof"  #AOF 文件的名称,默认为Appendonly.aof
    -   # Appendfsync always              #每次收到写命令就立即强制写入到磁盘,能保证完全持久化,但速度也最慢,不推荐
    -   Appendfsync everysec              #每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,推荐
    -   # Appendfsync no                  #完全依赖Linux,性能最好,但持久化没保证
    -  no-Appendfsync-on-rewrite yes     #在日志重写时,不进行命令追加,而将其放在缓冲区中
    -  auto-aof-rewrite-percentage 100   #当前AOF 文件大小是上次日志重写的AOF 文件大小的二倍时,自动启动新的日志重写过程。
    -  auto-aof-rewrite-min-size 64mb    #当前AOF 文件重写的最少值
            -7.6 故障排除案例
        -第8章 MongoDB——App后台新兴的数据库
            -8.1 简介
            -8.2 核心机制解析
                -8.2.1 MMAP(内存文件映射)
                -8.2.2 Journal日志
            -8.3 入门
                -8.3.1 基本操作
    -   [root@jeff ~]# /usr/local/mongodb/bin/mongo
    -   MongoDB shell version: 3.0.5
    -   connecting to: test
    -   use数据库名
    -   >db.person.insert({"name":"jeff","age":25})
    -   >db.person.insert({"name":"tom","age":26})
    -   >db.person.find()
    -   { "_id" : ObjectId("55cd29d229866714a4b512ab"), "name" : "jeff", "age" : 25 }
    -   { "_id" : ObjectId("55cd2b1729866714a4b512ad"), "name" : "tom", "age" : 26 }
    -   >db.person.find({"name":"jeff"})
    -   { "_id" : ObjectId("55cd29d229866714a4b512ab"), "name" : "jeff", "age" : 25 }
    -   >db.person.find({"age":{"$gt":25}})
    -   { "_id" : ObjectId("55cd2b1729866714a4b512ad"), "name" : "tom", "age" : 26 }
    -   >db.person.find({"age":{"$in":[25]}})
    -   { "_id" : ObjectId("55cd29d229866714a4b512ab"), "name" : "jeff", "age" : 25 }
    -   >db.person.find({"$or":[{"name":"jeff"},{"age":26}]})
    -   { "_id" : ObjectId("55cd29d229866714a4b512ab"), "name" : "jeff", "age" : 25 }
    -   { "_id" : ObjectId("55cd2b1729866714a4b512ad"), "name" : "tom", "age" : 26 }
    -   >db.person.find({"name":"jeff"})
    -   { "_id" : ObjectId("55cd29d229866714a4b512ab"), "name" : "jeff", "age" : 25 }
    -   >db.person.update({"name":"jeff"},{"name":"jeff","age":26})
    -   >db.person.find({"name":"jeff"})
    -   { "_id" : ObjectId("55cd29d229866714a4b512ab"), "name" : "jeff", "age" : 26 }
    -   >db.person.remove({"age":26})
    -   WriteResult({ "nRemoved" : 1 })
    -   >db.person.find()
    -   { "_id" : ObjectId("55cd29d229866714a4b512ab"), "name" : "jeff", "age" : 25 }
    -   >db.person.remove({})
    -   >db.person.find()
                -8.3.2 数组操作
    -   >db.arr.insert({ "fruit" : [ "Apple", "banana", "peach" ] })
    -   >db.arr.insert({ "fruit" : [ "Apple", "banana", "orange" ] })
    -   >db.arr.insert({ "fruit" : [ "Apple", "cherry", "orange" ] })
    -   >db.arr.find({"fruit":"banana"})
    -   { "_id" : ObjectId("55ce88dd678cb85541f1a290"), "fruit" : [ "Apple", "banana", "peach" ] }
    -   { "_id" : ObjectId("55ce88ea678cb85541f1a291"), "fruit" : [ "Apple", "banana", "orange" ] }
    -   >db.arr.find({"fruit":{"$all":["Apple","orange"]}})
    -   { "_id" : ObjectId("55ce88ea678cb85541f1a291"), "fruit" : [ "Apple", "banana", "orange" ] }
    -   { "_id" : ObjectId("55ce88f9678cb85541f1a292"), "fruit" : [ "Apple", "cherry", "orange" ] }
    -   >db.product.insert({"name":"shirt","price":200,"comments":[{"author":"to m","score":3},{"author":"jeff","score":5}]})
    -   >db.product.insert({"name":"suit","price":120,"comments":[{"author":"ter ry","score":4},{"author":"jeff ","score":2}]})
    -   >db.product.insert({"name":"coat","price":100,"comments":[{"author":"jon y","score":3},{"author":"jeff ","score":4}]})
    -   >db.product.find()
    -   { "_id" : ObjectId("55ce903cae319b66d78a494a"), "name" : "shirt", "price" : 200, "comments" : [ { "author" : "tom", "score" : 3 }, { "author": "jeff", "score" : 5 } ] }
    -   { "_id" : ObjectId("55ce9043ae319b66d78a494b"), "name" : "suit", "price" : 120, "comments" : [ { "author" : "terry", "score" : 4 }, { "author" : "jeff ", "score" : 2 } ] }
    -   { "_id" : ObjectId("55ce904cae319b66d78a494c"), "name" : "coat", "price" : 100, "comments" : [ { "author" : "jony", "score" : 3 }, { "author" : "jeff ", "score" : 4 } ] }
    -   >db.product.find({"comments":{"$elemMatch":{"author":"jeff","score":{"$g t":4}}}})
    -   { "_id" : ObjectId("55ce903cae319b66d78a494a"), "name" : "shirt", "price" : 200, "comments" : [ { "author" : "tom", "score" : 3 }, { "author": "jeff", "score" : 5 } ] }
                -8.3.3 实例演示MySQL和MongoDB设计数据库的区别
    -   /* 商品基本属性表 */
    -   CREATE TABLE IF NOT EXISTS `product` (
    -       `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    -       `name` VARCHAR(100) NOT NULL,
    -       `price` FLOAT(10,2) NOT NULL,
    -       PRIMARY KEY (`id`)
    -   );
    -    /* 商品额外属性表 */
    -   CREATE TABLE IF NOT EXISTS `product_params` (
    -       `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    -       `product_id` int(10) unsigned NOT NULL,
    -       `name` varchar(100) NOT NULL,
    -       `value` varchar(100) NOT NULL,
    -       PRIMARY KEY (`id`)
    -   );
    -   INSERT INTO `product` (`id`, `name`, `price`) VALUES
    -   (1, '大衣', 110.00),
    -   (2, 'iPhone 6',4788.00 ),
    -   (3, '小米 红米2A',499.00 ),
    -   (4, '小米 Note 全网通',2099.00 ),
    -   (5, '酷派 大神 F2',699.00 ),
    -   (6, '华为 P8青春版',1588.00 );
    -   INSERT INTO `product_params` (`id`, `product_id`, `name`, `value`) VALUES
    -   (1, 1, '颜色', '红'),          /* 大衣的颜色 */
    -   (2, 1, '尺寸', 'S'),           /* 大衣的尺寸 */
    -   (3, 2, '机型', 'iPhone'),      /* iPhone 6的机型 */
    -   (4, 2, '机身内存', '16'),      /* iPhone 6的机身内存 */
    -   (5, 3, '机型', 'Android'),     /* 小米 红米2A的机型 */
    -   (6, 3, '机身内存', '8'),       /* 小米 红米2A的机身内存 */
    -   (7, 4, '机型', 'Android'),     /* 小米 Note 全网通的机型 */
    -   (8, 4, '机身内存', '16'),      /* 小米 Note 全网通的机身内存 */
    -   (9, 5, '机型', 'Android'),     /* 酷派 大神 F2的机型 */
    -   (10, 5, '机身内存', '16'),     /* 酷派 大神 F2的机身内存 */
    -   (11, 6, '机型', 'Android'),    /* 华为 P8青春版的机型 */
    -   (12, 6, '机身内存', '16');     /* 华为 P8青春版的机身内存 */
    -   SELECT product_id FROM `product_params` WHERE name = '机型' AND value = 'Android';
    -   SELECT product_id FROM `product_params` WHERE name = '机身内存' AND value = 16;
    -   SELECT * FROM `product` WHERE price>1000 and id in(4,5,6)
    -   db.product.insert({"name":"大衣",
    -                     "price":110.00,
    -                     "params":[
    -                     {"name":  "尺寸", "value": "S"},
    -                     {"name": "颜色", "value": "红"},
    -                     ]
    -                    })
    -   db.product.insert({"name":"iPhone 6",
    -                      "price":4788.00,
    -                      "params": [
    -                      {"name": "机身内存", "value": 16},
    -                      {"name": "机型", "value": "iPhone"}
    -                      ]
    -                     })
    -   db.product.insert({"name":"小米 红米2A",
    -                      "price":499.00,
    -                      "params": [
    -                      {"name": "机身内存", "value": 8},
    -                      {"name": "机型", "value": "Android"}
    -                      ]
    -                     })
    -   db.product.insert({"name":"小米 Note 全网通",
    -                     "price":2099.00,
    -                     "params": [
    -                     {"name": "机身内存", "value": 16},
    -                     {"name": "机型", "value": "Android"}
    -                     ]
    -                    })
    -   db.product.insert({"name":"酷派 大神 F2",
    -                     "price":699.00,
    -                     "params": [
    -                     {"name": "机身内存", "value": 16},
    -                     {"name": "机型", "value": "Android"}
    -                     ]
    -                    })
    -   db.product.insert({"name":"华为 P8青春版",
    -                     "price":1588.00,
    -                     "params": [
    -                     {"name": "机身内存", "value": 16},
    -                     {"name": "机型", "value": "Android"}
    -                     ]
    -                    })
    -   db.product.find({"params": {
    -                    "$all":[
    -                        {$elemMatch: {"name": "机型", "value": "Android"}},
    -                        {$elemMatch: {"name": "机身内存", "value": 16}}
    -                    ]
    -                },
    -                "price":{"$gt":1000},
    -               })
    -   { "_id" : ObjectId("55d1d874ece7a0dc06b2c172"), "name" : "小米 Note 全网通", "price" : 2099, "params" : [ { "name" : "机型", "value" : "Android" }, { "name" : "机身内存", "value" : 16 } ] }
    -   { "_id" : ObjectId("55d1d874ece7a0dc06b2c174"), "name" : "华为 P8青春版", "price" : 1588, "params" : [ { "name" : "机型", "v alue" : "Android" }, { "name" : "机身内存", "value" : 16 } ] }
            -8.4 高可用集群
                -8.4.1 主从
                -8.4.2 副本集
                -8.4.3 分片
            -8.5 LBS——地理位置查询
    -   db.location.insert({ "name" : "jeff","coordinate" : { "longitude" :113.392237, "latitude" : 23.062429 }})
    -   db.location.insert({ "name" : "tom","coordinate" : { "longitude" : 113.392354, "latitude" : 23.062582 }})
    -   db.location.insert({ "name" : "mike","coordinate" : { "longitude" :113.392107, "latitude" : 23.062246 }})
    -   db.location.insert({ "name" : "lili","coordinate" : { "longitude" : 113.39972, "latitude" : 23.067753 }})
    -   db.location.insert({ "name" : "lucy","coordinate" : { "longitude" :113.399343, "latitude" : 23.067158 }})
    -   > db.location.ensureIndex({'coordinate':'2d'})
    -   > db.location.ensureIndex({'coordinate':'2dsphere'})
    -   db.location.find({"coordinate": {
    -           "$nearSphere": [113.392237, 23.062429],
    -           "spherical": true,
    -           "$maxDistance": 1000/6378137,
    -           "distanceMultiplier": 637813
    -       }
    -   })
    -   db.location.find({"coordinate": {
    -           "$nearSphere": [113.392237,23.062429],
    -           "spherical": true,
    -           "$maxDistance": 500/6378137,
    -           "distanceMultiplier": 637813
    -       }
    -   })
    -   "geoNear": "location",
    -   "near": [113.392237,23.062429],
    -   "spherical": true,
    -   "$maxDistance": 500/6378137,
    -   "distanceMultiplier": 6378137
    -   {
    -               "dis" : 20.825177011762033,
    -               "obj" : {
    -                   "_id" : ObjectId("55d6da748271c3157a70988d"),
    -                   "name" : "tom",
    -                   "coordinate" : {
    -                       "longitude" : 113.392354,
    -                       "latitude" : 23.062582
    -                   }
    -               }
    -           },
    -   db.location.find({
    -       "coordinate": {
    -           "$geoWithin": {
    -               $box :[ [113.39168,23.062726] , [113.392848,23.061973] ]
    -           }
    -       }
    -   })
            -8.6 MongoDB 3.0版本的改进
                -8.6.1 灵活的存储架构
                -8.6.2 性能提升7~10倍
                -8.6.3 存储空间最多减少80%
                -8.6.4 运维成本最多降低95%
        -第9章 App后台架构剖析
            -9.1 聊天App后台架构
                -9.1.1 移动互联网的网络特性
                -9.1.2 协议
    -书名页
    -书名页
    -书名页
    -书名页
    -书名页
    -书名页
    -   *参数个数CR LF
    -   $第一个参数的字符串占用字节数CR LF
    -   参数数据CR LF
    -   …
    -   $第N 个参数的字符串占用字节数字CR LF
    -   参数数据 CR LF
    -   *3\r\n$3\r\nset\r\n$4\r\nname\r\n$4\r\njeff\r\n
                -9.1.3 整体架构
            -9.2 社交App后台架构
                -9.2.1 基本表结构
                -9.2.2 推拉模式
                -9.2.3 数据库架构的演进
                -9.2.4 缓存架构的演进
            -9.3 LBS App后台架构
                -9.3.1 地理坐标详解
                -9.3.2 查找附近的人
                -9.3.3 基于MongoDB的LBS后台架构演进
            -9.4 推送服务器后台架构
                -9.4.1 Android推送
    -   http://test.com/1/server/get?key=Terry22&proto=1
    -   {
    -       "ret": 0,
    -       "data": {
    -        "server": "183.54.1.1:8065"  //IP:Port
    -       }
    -   http://test.com/1/msg/get?k=Terry22&m=13999084541836408 获取该key的所有离线消息
    -   SELECT mid, ttl, msg FROM private_msg WHERE skey=k AND mid>m ORDER BY mid
                -9.4.2 iOS推送
            -9.5 获得更多App后台架构资料
        -第10章 App后台架构的演进
            -10.1 架构的核心要素
                -10.1.1 高性能
                -10.1.2 高可用
                -10.1.3 可伸缩
                -10.1.4 可扩展
                -10.1.5 安全性
            -10.2 架构选型的要点
                -10.2.1 用成熟稳定的开源软件
                -10.2.2 尽可能使用云服务
            -10.3 架构的演进
                -10.3.1 单机部署
                -10.3.2 分布式部署
                -10.3.3 服务化
            -10.4 架构的特点
                -10.4.1 每个App的后台架构不会完全一样
                -10.4.2 架构的演进是由业务驱动的
                -10.4.3 架构不是为了炫耀技术
Copyright & copy 7dtime.com 2014-2018 all right reserved,powered by Gitbook该文件修订时间: 2018-09-02 17:55:57

results matching ""

    No results matching ""