├── .gitignore ├── 1服务器环境.md ├── 2安装redis.md ├── 3安装zookeeper.md ├── 4安装mpush.md ├── 5安装alloc服务.md ├── 6完整测试.md ├── README.md ├── SUMMARY.md └── assets ├── alloc01.png ├── alloc02.png ├── alloc03.png ├── alloc04.png ├── alloc05.png ├── mpush01.png ├── mpush02.png ├── mpush03.png ├── mpush04.png ├── mpush05.png ├── mpush06.png ├── redis01.png ├── redis02.png ├── redis03.png ├── redis04.png ├── test01.png ├── test02.png ├── test03.png ├── zookeeper01.png ├── zookeeper02.png ├── zookeeper03.png └── zookeeper04.png /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # Compiled binary addons (http://nodejs.org/api/addons.html) 20 | build/Release 21 | 22 | # Dependency directory 23 | # Deployed apps should consider commenting this line out: 24 | # see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git 25 | node_modules 26 | 27 | _book/ 28 | book.pdf 29 | book.epub 30 | book.mobi 31 | -------------------------------------------------------------------------------- /1服务器环境.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | | 主机 | IP | 端口 | 4 | | --- | --- | --- | 5 | | Redis | 103.246.161.44 | 6379 | 6 | | ZooKeeper | 103.246.161.44 | 2181 | 7 | | Mpush | 103.246.161.44 | 3000 | 8 | | Alloc | 103.246.161.44 | 9999 | 9 | 10 | 服务器版本为Centos7,最小化安装。 11 | 12 | note: 13 | 14 | 1)最小化安装,默认网卡没有开机自动启动,可以编辑网卡文件\(默认为ifcfg-eth0\),将ONBOOT修改为yes 15 | 16 | > \[root@localhost ~\]\# vim \/etc\/sysconfig\/network-scripts\/ifcfg-eth0 17 | > 18 | > **ONBOOT=yes** 19 | 20 | 2)安装系统基本依赖包,用于编译安装软件 21 | 22 | > \[root@localhost ~\]\# yum install net-tools vim wget make gcc g++ gc++ -y 23 | 24 | 3)关闭防火墙和SELinux,防止系统干扰导致部署不成功 25 | 26 | > \[root@localhost ~\]\# setenforce 0 27 | > 28 | > \[root@localhost ~\]\# iptables -F 29 | > 30 | > \[root@localhost ~\]\# iptables -X 31 | 32 | 33 | 34 | 安装JDK 35 | 36 | > \[root@localhost app\]\# ll 37 | > 38 | > -rw-------. 1 root root 181352138 Sep 6 22:54 jdk-8u101-linux-x64.tar.gz 39 | 40 | 1、安装JDK并设置环境变量 41 | 42 | > \[root@localhost app\]\# tar xf jdk-8u101-linux-x64.tar.gz 43 | > 44 | > \[root@localhost app\]\# ln -s jdk1.8.0\_101 jdk 45 | > 46 | > 设置JAVA环境变量 47 | > 48 | > \[root@localhost app\]\# vim \/etc\/profile.d\/java.sh 49 | > 50 | > JAVA\_HOME=\/app\/jdk 51 | > 52 | > PATH=$JAVA\_HOME\\/bin:$PATH 53 | > 54 | > CLASSPATH=.:$JAVA\_HOME\/lib\/dt.jar:$JAVA\_HOME\/lib\/tools.jar 55 | > 56 | > export JAVA\_HOME PATH CLASSPATH 57 | > 58 | > 给脚本执行权限 59 | > 60 | > \[root@localhost app\]\# chmod +x \/etc\/profile.d\/java.sh 61 | > 62 | > 讲JAVA环境变量应用到当前shell 63 | > 64 | > \[root@localhost app\]\# source \/etc\/profile.d\/java.sh 65 | > 66 | > \[root@localhost app\]\# java -version 67 | > 68 | > java version "1.8.0\_101" 69 | > 70 | > Java\(TM\) SE Runtime Environment \(build 1.8.0\_101-b13\) 71 | > 72 | > Java HotSpot\(TM\) 64-Bit Server VM \(build 25.101-b13, mixed mode\) 73 | 74 | -------------------------------------------------------------------------------- /2安装redis.md: -------------------------------------------------------------------------------- 1 | 一、Linux系统安装Redis 2 | 3 | [官网](http://redis.io/)下载Redis包,这里下载的是3.2.3版本 4 | 5 | 1、编译安装Redis 6 | 7 | > \[root@localhost ~\]\# mkdir \/app 8 | > 9 | > \[root@localhost ~\]\# cd \/app 10 | > 11 | > \[root@localhost ~\]\# wget http:\/\/download.redis.io\/releases\/redis-3.2.3.tar.gz 12 | > 13 | > 解压压缩包 14 | > 15 | > \[root@localhost ~\]\# tar xf redis-3.2.3.tar.gz 16 | > 17 | > \[root@localhost ~\]\# cd redis-3.2.3 18 | > 19 | > 编译Redis 20 | > 21 | > \[root@localhost redis-3.2.3\]\# make 22 | > 23 | > 安装Redis 24 | > 25 | > \[root@localhost redis-3.2.3\]\# make install 26 | > 27 | > cd src && make install 28 | > 29 | > make\[1\]: Entering directory \`\/app\/redis-3.2.3\/src' 30 | > 31 | > Hint: It's a good idea to run 'make test' ;\) 32 | > 33 | > INSTALL install 34 | > 35 | > INSTALL install 36 | > 37 | > INSTALL install 38 | > 39 | > INSTALL install 40 | > 41 | > INSTALL install 42 | > 43 | > make\[1\]: Leaving directory \`\/app\/redis-3.2.3\/src' 44 | 45 | 2、提供配置文件和基础数据目录(我这里将Redis执行文件复制到专门的目录) 46 | 47 | > \[root@localhost redis-3.2.3\]\# mkdir -pv \/app\/redis\/{bin,conf,log,db} 48 | > 49 | > mkdir: created directory ‘\/app\/redis’ 50 | > 51 | > mkdir: created directory ‘\/app\/redis\/bin’ 52 | > 53 | > mkdir: created directory ‘\/app\/redis\/conf’ 54 | > 55 | > mkdir: created directory ‘\/app\/redis\/log’ 56 | > 57 | > mkdir: created directory ‘\/app\/redis\/db’ 58 | > 59 | > \[root@localhost redis-3.2.3\]\# cd src 60 | > 61 | > 复制需要的二进制文件 62 | > 63 | > \[root@localhost src\]\# cp redis-benchmark redis-check-aof redis-check-rdb redis-cli redis-sentinel redis-server \/app\/redis\/bin\/ 64 | > 65 | > \[root@localhost src\]\# cd \/app\/redis 66 | > 67 | > 提供启动配置文件 68 | > 69 | > \[root@localhost redis\]\# vim conf\/redis.conf 70 | > 71 | > **daemonize yes** 72 | > 73 | > **protected-mode no** 74 | > 75 | > pidfile \/var\/run\/redis.pid 76 | > 77 | > port 6379 78 | > 79 | > timeout 0 80 | > 81 | > tcp-keepalive 0 82 | > 83 | > databases 16 84 | > 85 | > save 900 1 86 | > 87 | > save 300 10 88 | > 89 | > save 60 10000 90 | > 91 | > stop-writes-on-bgsave-error yes 92 | > 93 | > rdbcompression yes 94 | > 95 | > rdbchecksum yes 96 | > 97 | > dir \/app\/redis\/db 98 | > 99 | > dbfilename dump-6379.rdb 100 | > 101 | > loglevel notice 102 | > 103 | > logfile \/app\/redis\/log\/redis.log 104 | > 105 | > slave-serve-stale-data yes 106 | > 107 | > slave-read-only yes 108 | > 109 | > repl-disable-tcp-nodelay no 110 | > 111 | > slave-priority 100 112 | > 113 | > appendonly no 114 | > 115 | > appendfsync everysec 116 | > 117 | > no-appendfsync-on-rewrite no 118 | > 119 | > auto-aof-rewrite-percentage 100 120 | > 121 | > auto-aof-rewrite-min-size 64mb 122 | > 123 | > lua-time-limit 5000 124 | > 125 | > slowlog-log-slower-than 10000 126 | > 127 | > slowlog-max-len 128 128 | > 129 | > hash-max-ziplist-entries 512 130 | > 131 | > hash-max-ziplist-value 64 132 | > 133 | > list-max-ziplist-entries 512 134 | > 135 | > list-max-ziplist-value 64 136 | > 137 | > set-max-intset-entries 512 138 | > 139 | > zset-max-ziplist-entries 128 140 | > 141 | > zset-max-ziplist-value 64 142 | > 143 | > activerehashing yes 144 | > 145 | > client-output-buffer-limit normal 0 0 0 146 | > 147 | > client-output-buffer-limit slave 256mb 64mb 60 148 | > 149 | > client-output-buffer-limit pubsub 32mb 8mb 60 150 | > 151 | > hz 10 152 | > 153 | > aof-rewrite-incremental-fsync yes 154 | 155 | 3.启动Redis服务 156 | 157 | > \[root@localhost redis\]\# \/app\/redis\/bin\/redis-server \/app\/redis\/conf\/redis.conf 158 | > 159 | > 查看是否启动Redis服务,并监听指定端口 160 | > 161 | > ![](/assets/redis03.png) 162 | > 163 | > 这里可以看到,默认的6379已经处于监听状态 164 | 165 | 4.测试Redis 166 | 167 | ![](/assets/redis04.png) 168 | 169 | 5.查看Redis日志 170 | 171 | > \[root@localhost redis\]\# tailf \/app\/redis\/log\/redis.log 172 | 173 | 二、Windows安装Redis 174 | 175 | 下载地址[Github](https://github.com/MSOpenTech/redis/releases),这里redis-64.3.0.503版本 176 | 177 | 1.下载并解压,解压后如下 178 | 179 | ![](/assets/redis01.png) 180 | 181 | 2.使用cmd进入到Redis解压目录中,并使用脚本\(redis-server.exe redis.windows.conf\)执行即可,默认配置文件不需要修改 182 | 183 | ![](/assets/redis02.png) 184 | 185 | -------------------------------------------------------------------------------- /3安装zookeeper.md: -------------------------------------------------------------------------------- 1 | 从[官网](http://www.apache.org/dyn/closer.cgi/zookeeper/)直接下载Zookeeper最新版本\(Zookeeper支持Windows和Linux\) 2 | 3 | > \[root@localhost app\]\# ll 4 | > 5 | > -rw-------. 1 root root 22724574 Sep 6 23:02 zookeeper-3.4.9.tar.gz 6 | 7 | 一、Linux安装Zookeeper 8 | 9 | > \[root@localhost app\]\# tar xf zookeeper-3.4.9.tar.gz 10 | > 11 | > \[root@localhost app\]\# ln -s zookeeper-3.4.9 zookeeper 12 | > 13 | > \[root@localhost app\]\# cd zookeeper 14 | > 15 | > 提供配置文件 16 | > 17 | > \[root@localhost zookeeper\]\# cp conf\/zoo\_sample.cfg conf\/zoo.cfg 18 | 19 | 启动Zookeeper服务 20 | 21 | > \[root@localhost zookeeper\]\# bin\/zkServer.sh start 22 | > 23 | > ZooKeeper JMX enabled by default 24 | > 25 | > Using config: \/app\/zookeeper\/bin\/..\/conf\/zoo.cfg 26 | > 27 | > Starting zookeeper ... STARTED 28 | 29 | 查看端口监听 30 | 31 | > \[root@localhost zookeeper\]\# netstat -tplan \| grep 2181 32 | > 33 | > tcp6 0 0 :::2181 :::\* LISTEN 3180\/java 34 | 35 | ![](/assets/zookeeper03.png) 36 | 37 | 使用Zookeeper的客户端测试 38 | 39 | ![](/assets/zookeeper04.png) 40 | 41 | 二、Windows安装Zookeeper 42 | 43 | 使用上面下载的Zookeeper文件 44 | 45 | 1.下载并解压,解压后如下 46 | 47 | ![](/assets/zookeeper01.png) 48 | 49 | 2.提供配置文件 50 | 51 | 将conf目录下的zoo\_sample.conf重命名为zoo.conf 52 | 53 | 3.到bin目录下,双击zkServer.bat即可 54 | 55 | ![](/assets/zookeeper02.png) 56 | 57 | -------------------------------------------------------------------------------- /4安装mpush.md: -------------------------------------------------------------------------------- 1 | 一、Linux安装Mpush 2 | 3 | > \[root@localhost app\]\# tar xf mpush-release-0.0.5.tar.gz 4 | > 5 | > \[root@localhost app\]\# ln -s mpush-0.0.5 mpush 6 | > 7 | > 编辑Mpush配置文件\(注意,只需要修改mpush.conf配置文件即可,不需要修改reference.conf\),修改默认提供的Redis、Zookeeper服务器地址和端口信息\(因为我redis和zookeeper直接部署在本机,所以不用修改\)。 8 | > 9 | > \[root@localhost app\]\#vim conf\/mpush.conf 10 | > 11 | > 12 | > 13 | > 给脚本执行权限 14 | > 15 | > \[root@localhost mpush\]\# chmod +x bin\/\*.sh 16 | > 17 | > \[root@localhost mpush\]\# bin\/mp.sh start 18 | 19 | ![](/assets/mpush01.png) 20 | 21 | 查看启动情况和端口监听情况 22 | 23 | > \[root@localhost mpush\]\#netstat -tplan \| grep java 24 | 25 | ![](/assets/mpush02.png) 26 | 27 | 可以看到,主要端口\(3000、3001、3002\)已经启动 28 | 29 | 查看日志\(如果有错误,会在日志中提现\) 30 | 31 | ![](/assets/mpush03.png) 32 | 33 | 二、Windows安装Mpush 34 | 35 | 1.解压mpush-release-0.0.5.tar.gz 36 | 37 | ![](/assets/mpush04.png) 38 | 39 | 2.编辑Mpush配置文件\(注意,只需要修改mpush.conf配置文件即可,不需要修改reference.conf\),修改默认提供的Redis、Zookeeper服务器地址和端口信息\(因为我redis和zookeeper直接部署在本机,所以不用修改\)。 40 | 41 | 42 | 43 | 3.使用cmd进入到bin目录,启动Mpush\(使用如下脚本java -Dmp.conf=D:\mpush\mpush-0.0.5\conf\mpush.conf -jar bootstrap.jar\) 44 | 45 | ![](/assets/mpush05.png) 46 | 47 | ![](/assets/mpush06.png) 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /5安装alloc服务.md: -------------------------------------------------------------------------------- 1 | 一、Linux安装Mpush-Alloc 2 | 3 | > \[root@localhost app\]\# tar xf alloc-release-0.0.5.tar.gz 4 | > 5 | > \[root@localhost app\]\# ln -s mpush-alloc-0.0.5 mpush-alloc 6 | > 7 | > 编辑配置文件\(注意,这里不需要修改,如果分布式部署,修改zookeeper地址信息即可\)。 8 | > 9 | > \[root@localhost app\]\#vim conf\/mpush.conf 10 | > 11 | > 给脚本执行权限 12 | > 13 | > \[root@localhost mpush\]\# chmod +x bin\/\*.sh 14 | > 15 | > \[root@localhost mpush\]\# bin\/mp.sh start 16 | 17 | ![](/assets/alloc01.png) 18 | 19 | 查看日志和启动情况 20 | 21 | ![](/assets/alloc02.png) 22 | 23 | 浏览器测试 24 | 25 | ![](/assets/alloc05.png) 26 | 27 | 可以看到,已经有mpush服务的信息 28 | 29 | 30 | 31 | 二、Windows安装Mpush-Alloc 32 | 33 | 1.解压alloc-release-0.0.5.tar.gz 34 | 35 | 2.修改配置文件\(注意,这里不需要修改,如果分布式部署,修改zookeeper地址信息即可\)。 36 | 37 | 3.使用cmd进入到alloc的bin目录,使用如下命令启动\(java -Dmp.conf=D:\mpush\mpush-alloc-0.0.5\conf\mpush.conf -jar bootstrap.jar\) 38 | 39 | ![](/assets/alloc03.png) 40 | 41 | ![](/assets/alloc04.png) 42 | 43 | -------------------------------------------------------------------------------- /6完整测试.md: -------------------------------------------------------------------------------- 1 | 一、Android测试 2 | 3 | note:测试时候,要确保Android和Alloc、MPush在同一个局域网内,能相互访问,或者Alloc、MPush部署在公网外。我这里部署在公网服务器上。 4 | 5 | 1\) 填写Alloc服务器地址\(http:\/\/103.246.161.44:9999\/\),注意以http:\/\/开头,且加端口号 6 | 7 | 2)点击BIND按钮 8 | 9 | 3)填写发送的消息 10 | 11 | 4)点击Start Push 12 | 13 | 5)点击Send Push 14 | 15 | 正常情况,客户端会受到由服务器端推送过来的消息 16 | 17 | ![](/assets/test01.png) 18 | 19 | 2、模拟IM 20 | 21 | 客户端1使用Android手机,客户端2使用浏览器模拟,客户端2给客户端1发送消息。如果有两个手机也可以,将界面的to:填写为对方的userid即可。 22 | 23 | 手机端操作如下 24 | 25 | 1\) 填写Alloc服务器地址\(http:\/\/103.246.161.44:9999\/\),注意以http:\/\/开头,且加端口号 26 | 27 | 2)点击BIND按钮 28 | 29 | 3)在from输入自己的用户ID,user-0 30 | 31 | 4)点击Start Push 32 | 33 | 34 | 35 | 浏览器端打开测试地址\(http:\/\/103.246.161.44:9999\/html\) 36 | 37 | 输入手机端设置的用户ID\(from位置\),输入推送消息,点击send即可 38 | 39 | ![](/assets/test02.png) 40 | 41 | 手机端提示消息 42 | 43 | ![](/assets/test03.png) 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Mpush安装 2 | 3 | -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | * [Introduction](README.md) 4 | * [1.服务器环境](/1服务器环境.md) 5 | * [2.安装Redis](2安装redis.md) 6 | * [3.安装Zookeeper](3安装zookeeper.md) 7 | * [4.安装MPush](4安装mpush.md) 8 | * [5.安装Alloc服务](5安装alloc服务.md) 9 | * [6.完整测试](6完整测试.md) 10 | 11 | -------------------------------------------------------------------------------- /assets/alloc01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpusher/mpush-doc/8b27d4e4b021fae4ca095983e45e4fb402e6096e/assets/alloc01.png -------------------------------------------------------------------------------- /assets/alloc02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpusher/mpush-doc/8b27d4e4b021fae4ca095983e45e4fb402e6096e/assets/alloc02.png -------------------------------------------------------------------------------- /assets/alloc03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpusher/mpush-doc/8b27d4e4b021fae4ca095983e45e4fb402e6096e/assets/alloc03.png -------------------------------------------------------------------------------- /assets/alloc04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpusher/mpush-doc/8b27d4e4b021fae4ca095983e45e4fb402e6096e/assets/alloc04.png -------------------------------------------------------------------------------- /assets/alloc05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpusher/mpush-doc/8b27d4e4b021fae4ca095983e45e4fb402e6096e/assets/alloc05.png -------------------------------------------------------------------------------- /assets/mpush01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpusher/mpush-doc/8b27d4e4b021fae4ca095983e45e4fb402e6096e/assets/mpush01.png -------------------------------------------------------------------------------- /assets/mpush02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpusher/mpush-doc/8b27d4e4b021fae4ca095983e45e4fb402e6096e/assets/mpush02.png -------------------------------------------------------------------------------- /assets/mpush03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpusher/mpush-doc/8b27d4e4b021fae4ca095983e45e4fb402e6096e/assets/mpush03.png -------------------------------------------------------------------------------- /assets/mpush04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpusher/mpush-doc/8b27d4e4b021fae4ca095983e45e4fb402e6096e/assets/mpush04.png -------------------------------------------------------------------------------- /assets/mpush05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpusher/mpush-doc/8b27d4e4b021fae4ca095983e45e4fb402e6096e/assets/mpush05.png -------------------------------------------------------------------------------- /assets/mpush06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpusher/mpush-doc/8b27d4e4b021fae4ca095983e45e4fb402e6096e/assets/mpush06.png -------------------------------------------------------------------------------- /assets/redis01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpusher/mpush-doc/8b27d4e4b021fae4ca095983e45e4fb402e6096e/assets/redis01.png -------------------------------------------------------------------------------- /assets/redis02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpusher/mpush-doc/8b27d4e4b021fae4ca095983e45e4fb402e6096e/assets/redis02.png -------------------------------------------------------------------------------- /assets/redis03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpusher/mpush-doc/8b27d4e4b021fae4ca095983e45e4fb402e6096e/assets/redis03.png -------------------------------------------------------------------------------- /assets/redis04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpusher/mpush-doc/8b27d4e4b021fae4ca095983e45e4fb402e6096e/assets/redis04.png -------------------------------------------------------------------------------- /assets/test01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpusher/mpush-doc/8b27d4e4b021fae4ca095983e45e4fb402e6096e/assets/test01.png -------------------------------------------------------------------------------- /assets/test02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpusher/mpush-doc/8b27d4e4b021fae4ca095983e45e4fb402e6096e/assets/test02.png -------------------------------------------------------------------------------- /assets/test03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpusher/mpush-doc/8b27d4e4b021fae4ca095983e45e4fb402e6096e/assets/test03.png -------------------------------------------------------------------------------- /assets/zookeeper01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpusher/mpush-doc/8b27d4e4b021fae4ca095983e45e4fb402e6096e/assets/zookeeper01.png -------------------------------------------------------------------------------- /assets/zookeeper02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpusher/mpush-doc/8b27d4e4b021fae4ca095983e45e4fb402e6096e/assets/zookeeper02.png -------------------------------------------------------------------------------- /assets/zookeeper03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpusher/mpush-doc/8b27d4e4b021fae4ca095983e45e4fb402e6096e/assets/zookeeper03.png -------------------------------------------------------------------------------- /assets/zookeeper04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mpusher/mpush-doc/8b27d4e4b021fae4ca095983e45e4fb402e6096e/assets/zookeeper04.png --------------------------------------------------------------------------------