搜索词>>git 耗时0.0080
  • Spring Boot 2.0 使用Maven git-commit-id插件

    Spring Boot 2.0 使用Maven git-commit-id插件Spring Boot 2.0 使用Maven git-commit-id插件
  • window中使用tortoisegit(俗称小乌龟)提交代码到GitHub网站

    图文详解在window中如何使用tortoisegit(俗称小乌龟)提交代码到GitHub网站图文详解在window中如何使用tortoisegit(俗称小乌龟)提交代码到GitHub网站<br /> <br /> 1.下载git环境<br /> https://git-for-windows.github.io/<br /> 推荐使用下载工具下载,网页下载国内很慢<br /> <br /> 2.下载tortoisegit<br /> https://tortoisegit.org/<br /> 下载语言包(可选)<br /> <br /> 3.安装git环境<br /> 双击安装文件,一直下一步就ok<br /> <br /> 4.安装tortoisegit<br /> 双击安装文件,一直下一步就ok<br /> <br /> 5.配置tortoisegit<br /> 打开设置页面,如图1<br /> <img alt="图1" class="img-thumbnail" src="/assist/images/blog/db071e1e-f272-4985-a90d-9ab6cb40687e.png" /><br /> 图1<br /> 如果下载了语言包,设置语言<br /> 点击General->右边有个Language选择中文即可,如下图2<br /> <img alt="​图2" class="img-thumbnail" src="/assist/images/blog/fbd5aff5-0378-43b5-8aa3-c257519f3f34.png" /><br /> 图2<br /> <br /> 6.配置network<br /> 点击Network>SSH client,找到安装git的目录,下面有个sh.exe或者ssh.exe,如下图3<br /> <img alt="图3" class="img-thumbnail" src="/assist/images/blog/3dbb21e5-fd4a-45fc-9f73-882698fa8a18.png" /><br /> 图3<br /> 7.配置Git<br /> Git->Config Source  -->Global<br /> Name---->输入你的名字随意的<br /> Email:输入你的邮箱,随意<br /> 如下图4<br /> <img alt="图4" class="img-thumbnail" src="/assist/images/blog/abe2ff9e-75f7-4def-8994-0a132346f8a5.png" /><br /> 图4<br /> 8.去github网站登录账户创建一个项目<br /> GitHub创建项目,如图5<br /> <img alt="​图5" class="img-thumbnail" src="/assist/images/blog/cac5ebb9-9d02-4cbd-843d-183799daa841.png" /><br /> 图5<br /> 9.将GitHub创建的项目拉下来<br /> 鼠标右键选择->Git克隆弹出克隆面板,如图7注意输入url地址<br /> <img alt="图7" class="img-thumbnail" src="/assist/images/blog/ce769f78-35ff-4099-b583-80b1d05e0b99.png" /><br /> 图7<br /> 拉取完毕,如图8<br /> <img alt="​图8" class="img-thumbnail" src="/assist/images/blog/1b39671c-f449-4170-b4d7-34eb15d3dfc5.png" /><br /> 图8<br /> <br /> 10.打开拉下来的项目创建一个简单文件README.MD,文件是一个文本改名来的,内容随意输入,如图9<br /> <img alt="图9" class="img-thumbnail" src="/assist/images/blog/ce7a5c1c-2e76-4d92-9420-782ed2a4d3c7.png" /><br /> 图9<br /> <br /> 11.将新创建的文件加入版本管理,如图10<br /> <img alt="图10" class="img-thumbnail" src="/assist/images/blog/f7025301-43a1-4682-b24b-1676fe73eb86.png" /><br /> 图10<br /> 选择需要加入版本管理的文件,默认工具会选择所有需要未添加的文件,如图11<br /> <img alt="图11" class="img-thumbnail" src="/assist/images/blog/a6cb54cd-c08b-4f9b-9c5e-a3cfc19efc2e.png" /><br /> 图11<br /> 添加到管理成功,如图12<br /> <img alt="图12" class="img-thumbnail" src="/assist/images/blog/4754efa0-f57d-4d19-b2a4-17158b6578c0.png" /><br /> 图12<br /> <br /> 12.注意图12中添加完成后有个提交,点击提交到版本管理,如图13<br /> <img alt="图13" class="img-thumbnail" src="/assist/images/blog/94840f84-524b-4ad5-9116-a1211c01a421.png" /><br /> 图13<br /> 输入提交版本的日志,并选择提交模式,可以选择提交,或提交并推送,这里选择的提交,弹出推送的提示如图14<br /> <img alt="图14" class="img-thumbnail" src="/assist/images/blog/ab1582c0-6065-48f6-91b5-01d1ca37daf7.png" /><br /> 图14<br /> 选择确定将开始推送,推送过程中会要求输入用户和密码,如图15<br /> <img alt="图15" class="img-thumbnail" src="/assist/images/blog/4eff05ad-2294-4567-af35-e0e0e45ee6a0.png" /><br /> 图15<br /> 输入完成用户密码推送开始,推送完毕如图16:<br /> <img alt="图16" class="img-thumbnail" src="/assist/images/blog/2ee5443a-1d86-4b1f-86fd-4fc819b742ef.png" /><br /> 图16<br /> <br /> 13.查看推送内容,如图提交并推送的内容已经在GitHub网站上咯。<br /> <img alt="图17" class="img-thumbnail" src="/assist/images/blog/9bedc705-52c1-4646-91fc-c8745ff633db.png" /><br /> 图17<br />  
  • Idea Git Merge 操作不自动提交

    背景该方式用于合并代码非常有用背景该方式用于合并代码非常有用。步骤1:拉取需要合并的分支到本地步骤2:Merge提示:不要直接点右下角的分支,"Merge into current",该操作会合并后自动本地提交​​勾选需要合并的分支(例如上面的将master分支同步到dev-new-redis)勾选 "No commit" ,"No fast forward"两个项目(表示合并不本地提交)Commit Message ,提交说明,根据实际情况填写说明信息即可,也可不填写最后点击Merge其他1:查看合并的文件变化通过点击commit可以查看到本次提交的文件变化情况提交:​变化情况:​查看改动情况:​其他2:快速回滚本次合并再未进行本地提交前,可进行快速回滚​​注意:勾上 "Delete local copies of added files",勾上后才能删除新增文件,否则回滚后新增文件还在,只是没有版本控制最后点击,终止合并​快速回滚搞定。
  • TortoiseGit配置SSH秘钥

    TortoiseGit配置SSH秘钥,TortoiseGitTortoiseGit配置SSH秘钥<br /> <br /> 1.打开秘钥生成器PuTTYgen<br /> <img alt="打开秘钥生成器PuTTYgen" class="img-thumbnail" src="/assist/images/blog/708ca43d12c142109225289e872be93c.png" /><br /> <br /> 2.生成秘钥<br /> <img alt="点击生成见" class="img-thumbnail" src="/assist/images/blog/6d7901b7d54245d5bc033374d2c5e1b8.png" /><br /> <img alt="移动鼠标生成秘钥" class="img-thumbnail" src="/assist/images/blog/68b6505ff0434622a36c5b17fe7fe1d2.png" /><br /> 注意在生成过程中需要鼠标在鼠标移动区域移动。不然进度会停止。<br /> <br /> 3.将生成的公钥复制到git的网站配置中<br /> 生成的秘钥对<br /> <img alt="生成的秘钥对" class="img-thumbnail" src="/assist/images/blog/d7eb6a21b40644ebb489fa22ae27362c.png" /><br /> 复制到git配置中心的秘钥管理<br /> <img alt="复制到git配置中心的秘钥管理" class="img-thumbnail" src="/assist/images/blog/bc603388c6ca4f1aababbace0bfc14f2.png" /><br /> <br /> 4.保存私钥到本地<br /> <img alt="保持私钥到本地" class="img-thumbnail" src="/assist/images/blog/2cadfb56b69d427a8a54ad893304aca7.png" /><br /> <img alt="保持私钥到本地" class="img-thumbnail" src="/assist/images/blog/ce79cc7c7c224a89bd11d70b333973c4.png" /><br /> <img alt="保持私钥到本地" class="img-thumbnail" src="/assist/images/blog/b3d3be4701344e50af9cf9e79f1c5b7f.png" /><br /> <br /> 5.配置TortoiseGit使用的客户端为putty的<br /> <img alt="配置TortoiseGit使用的客户端为putty的" class="img-thumbnail" src="/assist/images/blog/7f91f6f59ac44172b4872f04a972715f.png" /><br /> <img alt="配置TortoiseGit使用的客户端为putty的2" class="img-thumbnail" src="/assist/images/blog/3f671001c8604958985f47978532c141.png" /><br /> <br /> 6.下载通过密钥对加密的git私服项目<br /> <img alt="下载通过密钥对加密的git私服项目" class="img-thumbnail" src="/assist/images/blog/4381cb7255c541e3b6ebeac758211483.png" /><br /> 注意下载的时候加载秘钥位置<br /> <br /> 7.配置个人的秘钥库,不用每次都在clone操作的时候Load Putty Key<br /> <img alt="配置个人的秘钥库,不用每次都在clone操作的时候Load Putty Key1" class="img-thumbnail" src="/assist/images/blog/4a927fcbb2ee42cdafebda5004dc48ac.png" /><br /> <img alt="配置个人的秘钥库,不用每次都在clone操作的时候Load Putty Key2" class="img-thumbnail" src="/assist/images/blog/0a09345bdcc4458ca810fc3f08b79549.png" /><br /> <img alt="配置个人的秘钥库,不用每次都在clone操作的时候Load Putty Key3" class="img-thumbnail" src="/assist/images/blog/c2c6b88e61894a84810c63a5912a4c4c.png" /><br /> <img alt="配置个人的秘钥库,不用每次都在clone操作的时候Load Putty Key4" class="img-thumbnail" src="/assist/images/blog/1289a60fc48541eca5733519f0ffe33c.png" /><br /> <br /> 这时候clone的时候就不用再加载私钥了<br /> <img alt="配置个人的秘钥库,不用每次都在clone操作的时候Load Putty Key5" class="img-thumbnail" src="/assist/images/blog/9a270eb6fb3b450ab5061bbb28ae39d6.png" /><br /> <br /> <br />  
  • redis 命令查看使用情况redis info命令详解_redis查看内存使用情况

    redis 命令查看使用情况redis info命令详解,redis查看内存使用情况。redis info命令的详细解释<p>通过redis-cli连接到redis服务</p> <pre> <code class="language-html">redis-cli -h 192.168.1.3 -p 6300 192.168.1.3:6300> 192.168.1.3:6300> auth pass 192.168.1.3:6300> info all</code></pre> <pre> <code class="language-bash"># Server(服务器信息) redis_version:3.0.0                              #redis服务器版本 redis_git_sha1:00000000                  #Git SHA1 redis_git_dirty:0                                    #Git dirty flag redis_build_id:6c2c390b97607ff0    #redis build id redis_mode:cluster                              #运行模式,单机或者集群 os:Linux 2.6.32-358.2.1.el6.x86_64 x86_64 #redis服务器的宿主操作系统 arch_bits:64                                         #架构(32或64位) multiplexing_api:epoll                        #redis所使用的事件处理机制 gcc_version:4.4.7                                #编译redis时所使用的gcc版本 process_id:12099                               #redis服务器进程的pid run_id:63bcd0e57adb695ff0bf873cf42d403ddbac1565  #redis服务器的随机标识符(用于sentinel和集群) tcp_port:9021                                #redis服务器监听端口 uptime_in_seconds:26157730   #redis服务器启动总时间,单位是秒 uptime_in_days:302                    #redis服务器启动总时间,单位是天 hz:10                                #redis内部调度(进行关闭timeout的客户端,删除过期key等等)频率,程序规定serverCron每秒运行10次。 lru_clock:14359959      #自增的时钟,用于LRU管理,该时钟100ms(hz=10,因此每1000ms/10=100ms执行一次定时任务)更新一次。 config_file:/redis_cluster/etc/9021.conf  #配置文件路径 # Clients(已连接客户端信息) connected_clients:1081       #已连接客户端的数量(不包括通过slave连接的客户端) client_longest_output_list:0 #当前连接的客户端当中,最长的输出列表,用client list命令观察omem字段最大值 client_biggest_input_buf:0   #当前连接的客户端当中,最大输入缓存,用client list命令观察qbuf和qbuf-free两个字段最大值 blocked_clients:0                   #正在等待阻塞命令(BLPOP、BRPOP、BRPOPLPUSH)的客户端的数量 # Memory(内存信息) used_memory:327494024                 #由redis分配器分配的内存总量,以字节为单位 used_memory_human:312.32M       #以人类可读的格式返回redis分配的内存总量 used_memory_rss:587247616         #从操作系统的角度,返回redis已分配的内存总量(俗称常驻集大小)。这个值和top命令的输出一致 used_memory_peak:1866541112    #redis的内存消耗峰值(以字节为单位)  used_memory_peak_human:1.74G #以人类可读的格式返回redis的内存消耗峰值 used_memory_lua:35840                   #lua引擎所使用的内存大小(以字节为单位) mem_fragmentation_ratio:1.79          #used_memory_rss和used_memory之间的比率,小于1表示使用了swap,大于1表示碎片比较多 mem_allocator:jemalloc-3.6.0            #在编译时指定的redis所使用的内存分配器。可以是libc、jemalloc或者tcmalloc # Persistence(rdb和aof的持久化相关信息) loading:0                                                    #服务器是否正在载入持久化文件 rdb_changes_since_last_save:28900855 #离最近一次成功生成rdb文件,写入命令的个数,即有多少个写入命令没有持久化 rdb_bgsave_in_progress:0                  #服务器是否正在创建rdb文件 rdb_last_save_time:1482358115        #离最近一次成功创建rdb文件的时间戳。当前时间戳 - rdb_last_save_time=多少秒未成功生成rdb文件 rdb_last_bgsave_status:ok                   #最近一次rdb持久化是否成功 rdb_last_bgsave_time_sec:2                #最近一次成功生成rdb文件耗时秒数 rdb_current_bgsave_time_sec:-1        #如果服务器正在创建rdb文件,那么这个域记录的就是当前的创建操作已经耗费的秒数 aof_enabled:1                                          #是否开启了aof aof_rewrite_in_progress:0                     #标识aof的rewrite操作是否在进行中 aof_rewrite_scheduled:0               #rewrite任务计划,当客户端发送bgrewriteaof指令,如果当前rewrite子进程正在执行,那么将客户端请求的bgrewriteaof变为计划任务,待aof子进程结束后执行rewrite  aof_last_rewrite_time_sec:-1            #最近一次aof rewrite耗费的时长 aof_current_rewrite_time_sec:-1      #如果rewrite操作正在进行,则记录所使用的时间,单位秒 aof_last_bgrewrite_status:ok             #上次bgrewriteaof操作的状态 aof_last_write_status:ok                     #上次aof写入状态 aof_current_size:4201740                 #aof当前尺寸 aof_base_size:4201687                    #服务器启动时或者aof重写最近一次执行之后aof文件的大小 aof_pending_rewrite:0                       #是否有aof重写操作在等待rdb文件创建完毕之后执行? aof_buffer_length:0                             #aof buffer的大小 aof_rewrite_buffer_length:0              #aof rewrite buffer的大小 aof_pending_bio_fsync:0                  #后台I/O队列里面,等待执行的fsync调用数量 aof_delayed_fsync:0                          #被延迟的fsync调用数量 # Stats(一般统计信息) total_connections_received:209561105 #新创建连接个数,如果新创建连接过多,过度地创建和销毁连接对性能有影响,说明短连接严重或连接池使用有问题,需调研代码的连接设置 total_commands_processed:2220123478  #redis处理的命令数 instantaneous_ops_per_sec:279                  #redis当前的qps,redis内部较实时的每秒执行的命令数 total_net_input_bytes:118515678789          #redis网络入口流量字节数 total_net_output_bytes:236361651271       #redis网络出口流量字节数 instantaneous_input_kbps:13.56                  #redis网络入口kps instantaneous_output_kbps:31.33               #redis网络出口kps rejected_connections:0                                   #拒绝的连接个数,redis连接个数达到maxclients限制,拒绝新连接的个数 sync_full:1                                                          #主从完全同步成功次数 sync_partial_ok:0                                             #主从部分同步成功次数 sync_partial_err:0                                            #主从部分同步失败次数 expired_keys:15598177                                #运行以来过期的key的数量 evicted_keys:0                                                 #运行以来剔除(超过了maxmemory后)的key的数量 keyspace_hits:1122202228                          #命中次数 keyspace_misses:577781396                     #没命中次数 pubsub_channels:0                                       #当前使用中的频道数量 pubsub_patterns:0                                         #当前使用的模式的数量 latest_fork_usec:15679                                 #最近一次fork操作阻塞redis进程的耗时数,单位微秒 migrate_cached_sockets:0                          # # Replication(主从信息,master上显示的信息) role:master                               #实例的角色,是master or slave connected_slaves:1              #连接的slave实例个数 slave0:ip=192.168.64.104,port=9021,state=online,offset=6713173004,lag=0 #lag从库多少秒未向主库发送REPLCONF命令 master_repl_offset:6713173145  #主从同步偏移量,此值如果和上面的offset相同说明主从一致没延迟 repl_backlog_active:1                   #复制积压缓冲区是否开启 repl_backlog_size:134217728    #复制积压缓冲大小 repl_backlog_first_byte_offset:6578955418  #复制缓冲区里偏移量的大小 repl_backlog_histlen:134217728   #此值等于 master_repl_offset - repl_backlog_first_byte_offset,该值不会超过repl_backlog_size的大小 # Replication(主从信息,slave上显示的信息) role:slave                                        #实例的角色,是master or slave master_host:192.168.64.102       #此节点对应的master的ip master_port:9021                          #此节点对应的master的port master_link_status:up                   #slave端可查看它与master之间同步状态,当复制断开后表示down master_last_io_seconds_ago:0  #主库多少秒未发送数据到从库? master_sync_in_progress:0        #从服务器是否在与主服务器进行同步 slave_repl_offset:6713173818   #slave复制偏移量 slave_priority:100                          #slave优先级 slave_read_only:1                         #从库是否设置只读 connected_slaves:0                      #连接的slave实例个数 master_repl_offset:0          repl_backlog_active:0                  #复制积压缓冲区是否开启 repl_backlog_size:134217728   #复制积压缓冲大小 repl_backlog_first_byte_offset:0 #复制缓冲区里偏移量的大小 repl_backlog_histlen:0           #此值等于 master_repl_offset - repl_backlog_first_byte_offset,该值不会超过repl_backlog_size的大小 # CPU(CPU计算量统计信息) used_cpu_sys:96894.66             #将所有redis主进程在核心态所占用的CPU时求和累计起来 used_cpu_user:87397.39           #将所有redis主进程在用户态所占用的CPU时求和累计起来 used_cpu_sys_children:6.37     #将后台进程在核心态所占用的CPU时求和累计起来 used_cpu_user_children:52.83 #将后台进程在用户态所占用的CPU时求和累计起来 # Commandstats(各种不同类型的命令的执行统计信息) cmdstat_get:calls=1664657469,usec=8266063320,usec_per_call=4.97   #call每个命令执行次数,usec总共消耗的CPU时长(单位微秒),平均每次消耗的CPU时长(单位微秒) # Cluster(集群相关信息) cluster_enabled:1   #实例是否启用集群模式 # Keyspace(数据库相关的统计信息) db0:keys=194690,expires=191702,avg_ttl=3607772262 #db0的key的数量,以及带有生存期的key的数,平均存活时间</code></pre>
  • rocketmq 官网下载安装及配置教程

    Apache rocketmq 官网下载、Apache rocketmq 安装和Apache rocketmq 配置。由于rocketmq是阿里捐赠给Apache的。目前3.x以下版本为阿里版本。4.x为Apache托管版本。这里要说的是Apache的4.x版本。<h2>引言</h2> <p>    本文将讲解从Apache rocketmq 官网下载、Apache rocketmq 安装和Apache rocketmq 配置。由于rocketmq是阿里捐赠给Apache的。目前3.x以下版本为阿里版本。4.x为Apache托管版本。这里要说的是Apache的4.x版本。操作系统环境为centos6/7<br /> 1.准备工作</p> 由于目前Apache没有提供直编译的下载文件。我们需要自己去GitHub下载源文件进行编译才能使用。因其环境是Java。所以需要使用jdk(注意必须是jdk,jre不能编译程序)<br /> 1.1需要的环境 <ul> <li>64位操作系统</li> <li>64位jdk1.8+</li> <li>maven 3.2+</li> <li>Git(用于下载源码。可手动下载则无需安装)</li> </ul> <h2>2.编译工作</h2> 2.1环境:  <br /> 由于我所使用的服务器上只有jre,也不想去服务器折腾编译环境所以我把编译工作放在了windows系统上。jdk的安装及配置可参考<a rel="" href="http://www.leftso.com/blog/35.html" rel="external nofollow" target="_blank">http://www.leftso.com/blog/35.html</a>。maven去 Apache官网下载编译好的版本。将maven的bin目录添加到windows系统的环境变量path中即可。该操作可以参考jdk的环境变量配置。<br /> 2.2rocketmq源码下载<br /> Apache rocketmq的源码GitHub地址为:https://github.com/apache/incubator-rocketmq/archive/rocketmq-all-4.1.0-incubating.tar.gz<br /> 下载后解压放在一个文件夹里面。<br /> 2.3编译<br /> 打开windows的cmd窗口。切换至解压后的rocketmq源文件根目录。执行命令: <pre> <code>mvn -Prelease-all -DskipTests clean install -U</code></pre> 这个步骤需要的时间可能有点长。因为maven需要下载相关的依赖文件。<br /> 直到出现以下内容则为编译成功:<br /> <img alt="编译rocketmq成功" class="img-thumbnail" src="/assist/images/blog/8783ac7f5bf148f582112bfcb11e592d.png" /> <h2>3.上传项目至服务器</h2>   为了偷懒。或者说保持和Apache操作一致。我将编译后的整个项目上传至服务。我存放路径为/user/local/rocketmq/incubator-rocketmq(可根据实际情况修改,incubator-rocketmq为项目的源码根目录) <h2>4.配置rocketmq内存</h2>   由于默认的rockertmq内存配置有点大。server的默认配置为4Gb,broker的默认配置为8Gb。测试机可能没有那么大的内存。则会导致各种启动失败。<br /> 切换至/usr/local/rocketmq/incubator-rocketmq/distribution/target/apache-rocketmq/bin目录。修改runserver.sh和runbroker.sh<br /> 使用vi打开runserver.sh并找到JVM Configuration配置将其修改:<br /> <img alt="jvm内存修改" class="img-thumbnail" src="/assist/images/blog/17ab176c3b7f452589d43f7e2554fab7.png" /><br /> 这里的值可以根据具体情况来修改。<br /> 同样打开文件runbroker.sh修改jvm参数<br /> <br /> 最后将整个目录文件添加可执行权限。 <pre> <code>chmod 755 *</code></pre> <h2>5.启动停止rockermq服务</h2> 5.1启动name server<br /> 命令: <pre> <code>nohup sh bin/mqnamesrv &</code></pre> 查看启动情况<br /> 命令: <pre> <code>tail -f ~/logs/rocketmqlogs/namesrv.log</code></pre> <img alt="name server start success" class="img-thumbnail" src="/assist/images/blog/cb003f6bdc7a40b086b4ce1c79e0054c.png" /><br /> 5.2启动broker服务<br /> <br /> 启动命令: <pre> <code>nohup sh bin/mqbroker -n localhost:9876 &</code></pre> <br /> 查看启用情况: <pre> <code>tail -f ~/logs/rocketmqlogs/broker.log </code></pre> <img alt="broker success" class="img-thumbnail" src="/assist/images/blog/aef78ae1961844ab92eb1887c0ba796f.png" /><br /> <br /> 5.3停止name server 或者broker<br /> 切换至/usr/local/rocketmq/incubator-rocketmq/distribution/target/apache-rocketmq/bin目录<br /> 停止name server命令: <pre> <code class="language-html">[root@localhost bin]# pwd /usr/local/rocketmq/incubator-rocketmq/distribution/target/apache-rocketmq/bin [root@localhost bin]# ./mqshutdown namesrv The mqnamesrv(3077) is running... Send shutdown request to mqnamesrv(3077) OK</code></pre> <br /> 停止broker命令: <pre> <code class="language-html">[root@localhost bin]# ./mqshutdown broker The mqbroker(3104) is running... Send shutdown request to mqbroker(3104) OK [1]- Exit 143 nohup sh bin/mqnamesrv (wd: /usr/local/rocketmq/incubator-rocketmq/distribution/target/apache-rocketmq) (wd now: /usr/local/rocketmq/incubator-rocketmq/distribution/target/apache-rocketmq/bin) [root@localhost bin]# </code></pre> <br />  
  • spring boot使用Jenkins部署Spring Boot项目

    spring boot使用Jenkins部署Spring Boot项目<p>jenkins是devops神器,本篇文章介绍如何安装和使用jenkins部署Spring Boot项目</p> <p>jenkins搭建 部署分为三个步骤;</p> <ul> <li> <p>第一步,jenkins安装</p> </li> <li> <p>第二步,插件安装和配置</p> </li> <li> <p>第三步,Push SSH</p> </li> <li> <p>第四步,部署项目</p> </li> </ul> <h2>第一步 ,jenkins安装</h2> <p>准备环境:</p> <p>JDK:1.8<br /> Jenkins:2.83 Centos:7.3<br /> maven 3.5‘</p> <blockquote> <p>jdk默认已经安装完成</p> </blockquote> <h3>配置maven</h3> <p>版本要求maven3.5.0</p> <p>软件下载</p> <pre> <code class="language-html">wget http://mirror.bit.edu.cn/apache/maven/maven-3/3.5.0/binaries/apache-maven-3.5.0-bin.tar.gz</code></pre> <p>安装</p> <pre> <code class="language-bash">## 解压 tar vxf apache-maven-3.5.0-bin.tar.gz ## 移动 mv apache-maven-3.5.0 /usr/local/maven3</code></pre> <p>修改环境变量, 在/etc/profile中添加以下几行</p> <pre> <code class="language-html">MAVEN_HOME=/usr/local/maven3 export MAVEN_HOME export PATH=${PATH}:${MAVEN_HOME}/bin</code></pre> <p>记得执行 <code>source/etc/profile</code>使环境变量生效。</p> <p>验证 最后运行 <code>mvn-v</code>验证maven是否安装成功</p> <h3>配置防护墙</h3> <p>关闭防护墙</p> <pre> <code class="language-html">#centos7 systemctl stop firewalld.service ============================== #以下为:centOS 6.5关闭防火墙步骤 #关闭命令:   service iptables stop #永久关闭防火墙: chkconfig iptables off</code></pre> <p>两个命令同时运行,运行完成后查看防火墙关闭状态</p> <pre> <code class="language-html">service iptables status</code></pre> <h3>jenkins 安装</h3> <p>下载<br />  </p> <pre> <code class="language-html">cd /opt wget http://mirrors.jenkins.io/war/2.83/jenkins.war</code></pre> <p>启动服务</p> <pre> <code class="language-html">​​​​​​​java -jar jenkins.war &</code></pre> <p>Jenkins 就启动成功了!它的war包自带Jetty服务器</p> <p>第一次启动Jenkins时,出于安全考虑,Jenkins会自动生成一个随机的口令。<strong>注意控制台输出的口令,复制下来</strong>,然后在浏览器输入密码:</p> <pre> <code class="language-html">INFO: ************************************************************* ************************************************************* ************************************************************* Jenkins initial setup is required. An admin user has been created and a password generated. Please use the following password to proceed to installation: 0cca37389e6540c08ce6e4c96f46da0f This may also be found at: /root/.jenkins/secrets/initialAdminPassword ************************************************************* ************************************************************* *************************************************************</code></pre> <p>访问 浏览器访问: <code>http://localhost:8080/<br /> <img alt="安装" class="img-thumbnail" src="/assist/images/blog/dc38e97e558148d1953ee91e9630bf50.jpg" /></code><br />  </p> <p>输入:0cca37389e6540c08ce6e4c96f46da0f</p> <p>进入用户自定义插件界面,建议选择安装官方推荐插件,因为安装后自己也得安装:<br /> <img alt="install 1" class="img-thumbnail" src="/assist/images/blog/badf16beeea84c8a8b119fc7cf5e0d7f.jpg" /><br /> 接下来是进入插件安装进度界面:<br /> <img alt="install 2" class="img-thumbnail" src="/assist/images/blog/c5901b1554cc476a87d2806b048d3c8f.jpg" /><br /> 插件一次可能不会完全安装成功,可以点击Retry再次安装,直到全部安装成功。<br /> <img alt="install 3" class="img-thumbnail" src="/assist/images/blog/f88e983c46a746fb9ab1f7adc3c1f35c.jpg" /><br /> 等待一段时间之后,插件安装完成,配置用户名密码:<br /> <img alt="install 5" class="img-thumbnail" src="/assist/images/blog/d99345eac5e44be7bf9573da39832f99.jpg" /><br />  </p> <p>输入:admin/admin</p> <p>系统管理-》全局工具配置 jdk路径,<br /> <img alt="install 6" class="img-thumbnail" src="/assist/images/blog/049f7d98e1e64175919eb75eefd662f0.jpg" /></p> <h2>第二步,插件安装和配置</h2> <p>有很多插件都是选择的默认的安装的,所以现在需要我们安装的插件不多,Git plugin和Maven Integration plugin,publish over SSH。</p> <p>插件安装:系统管理 > 插件管理 > 可选插件,勾选需要安装的插件,点击直接安装或者下载重启后安装<br /> <img alt="install 7" class="img-thumbnail" src="/assist/images/blog/c4944230d3fb4b668c5f606441d2575f.jpg" /></p> <h3>配置全局变量</h3> <p>系统管理 > 全局工具配置</p> <p><strong>JDK</strong></p> <p>配置本地JDK的路径,去掉勾选自动安装<br /> <img alt="install 8" class="img-thumbnail" src="/assist/images/blog/590fb0fbbb7047df96ea276960438285.png" /><br /> <br />  </p> <p><strong>Maven</strong></p> <p>配置本地maven的路径,去掉勾选自动安装<br /> <img alt="install 9" class="img-thumbnail" src="/assist/images/blog/deb59e78535c45fe8bb914b592491e6a.png" /></p> <p>其它内容可以根据自己的情况选择安装。</p> <h3>配置 SSH免登陆</h3> <p>ssh的配置可使用密钥,也可以使用密码,这里我们使用密钥来配置,在配置之前先配置好jenkins服务器和应用服务器的密钥认证 <strong>jenkins服务器</strong>上生成密钥对,使用 <code>ssh-keygen-t rsa</code>命令</p> <p>输入下面命令 一直回车,一个矩形图形出现就说明成功,在~/.ssh/下会有私钥idrsa和公钥idrsa.pub</p> <pre> <code class="language-html">ssh-keygen -t rsa</code></pre> <p>将<strong>jenkins服务器</strong>的公钥 <code>id_rsa.pub</code>中的内容复制到<strong>应用服务器</strong> 的~/.ssh/下的 <code>authorized_keys</code>文件</p> <pre> <code class="language-html">ssh-copy-id -i id_rsa.pub 192.168.0.xx chmod 644 authorized_keys</code></pre> <p>在<strong>应用服务器</strong>上重启ssh服务, <code>service sshd restart</code>现在jenkins服务器可免密码直接登陆应用服务器</p> <p>之后在用ssh B尝试能否免密登录B服务器,如果还是提示需要输入密码,则有以下原因</p> <ul> <li>a. 非root账户可能不支持ssh公钥认证(看服务器是否有限制)</li> <li>b. 传过来的公钥文件权限不够,可以给这个文件授权下 chmod 644 authorized_keys</li> <li>c. 使用root账户执行ssh-copy-id -i ~/.ssh/idrsa.pub 这个指令的时候如果需要输入密码则要配置sshdconfig<br />  </li> </ul> <pre> <code class="language-html">vi /etc/ssh/sshd_config #内容 PermitRootLogin no</code></pre> <p>修改完后要重启sshd服务</p> <pre> <code class="language-html">service sshd restart</code></pre> <p>最后,如果可以SSH IP 免密登录成功说明SSH公钥认证成功。</p> <h2>第三步,Push SSH</h2> <p>系统管理 > 系统设置</p> <p>选择 Publish over SSH<br /> <img alt="install 10" class="img-thumbnail" src="/assist/images/blog/d7cb7603ce754991b4545d037723c95b.jpg" /><br />  </p> <p>Passphrase 不用设置 Path to key 写上生成的ssh路径: <code>/root/.ssh/id_rsa</code></p> <p>下面的SSH Servers是重点</p> <p>Name 代表这个服务的名字,待会要根据它来选择 Hostname 配置应用服务器的地址 ,Username 配置linux登陆用户名,Remote Directory 不填。</p> <blockquote> <p>点击下方增加可以添加多个应用服务器的地址</p> </blockquote> <h2>第四步,部署项目</h2> <p>首页点击<strong>新建</strong>:输入项目名称<br /> <img alt="install 11" class="img-thumbnail" src="/assist/images/blog/6839c4c2b4fc459997b8da3358ba5ab5.jpg" /><br />  </p> <p>下方选择构建一个maven项目,点击确定。</p> <p>勾选<strong>丢弃旧的构建</strong>,选择是否备份被替换的旧包。我这里选择备份最近的10个<br /> <img alt="install2" class="img-thumbnail" src="/assist/images/blog/7b39a1d66e2141bb85be6ab5b06af713.jpg" />源码管理,选择svn,配置SVN相关信息,点击add可以输入svn的账户和密码<br /> <img alt="install 13" class="img-thumbnail" src="/assist/images/blog/b56df59efbe846858d6246d1d3aadcef.jpg" /></p> <p>svn地址:http://192.168.0.xx/svn/xxx@HEAD, <code>@HEAD</code>意思取最新版本</p> <p>构建环境中勾选“Add timestamps to the Console Output”,代码构建的过程中会将日志打印出来<br /> <img alt="install 14" class="img-thumbnail" src="/assist/images/blog/161fd6e0dab344febfd77e51840044aa.png" /><br />  </p> <p>在Build中输入打包前的mvn命令,如:</p> <pre> <code class="language-html">clean install -Dmaven.test.skip=true -Ptest</code></pre> <p>意思是:排除测试的包内容,使用后缀为test的配置文件。<br /> <img alt="install 15" class="img-thumbnail" src="/assist/images/blog/3fb887bd57584b6ea9741242c227beeb.png" /><br /> Post Steps 选择 Run only if build succeeds<br /> <img alt="install 16" class="img-thumbnail" src="/assist/images/blog/1fb7cbbb0a2b47e4a51984fad847011c.png" /><br /> 点击<strong>Add post-build step</strong>,选择 Send files or execute commands over SSH<br /> <img alt="install 17" class="img-thumbnail" src="/assist/images/blog/7d0297473cb74033951da9881d7f7618.jpg" />Name选择上面配置的Push SSH<br /> <img alt="install 18" class="img-thumbnail" src="/assist/images/blog/bba4530a46d64d30bf4e47cc48850625.jpg" /><br />  </p> <p>Source files配置:target/xxx-0.0.1-SNAPSHOT.jar 项目jar包名 ;Remove prefix:target/ ;Remote directory:Jenkins-in/ 代码应用服务器的目录地址;Exec command:Jenkins-in/xxx.sh 应用服务器对应的脚本。</p> <p>需要在应用服务器创建文件夹:Jenkins-in,在文件夹中复制一下脚本内容:xxx.sh<br />  </p> <pre> <code class="language-html">DATE=$(date +%Y%m%d) export JAVA_HOME PATH CLASSPATH JAVA_HOME=/usr/java/jdk1.8.0_131 PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$CLASSPATH DIR=/root/xxx JARFILE=xxx-0.0.1-SNAPSHOT.jar if [ ! -d $DIR/backup ];then   mkdir -p $DIR/backup fi cd $DIR ps -ef | grep $JARFILE | grep -v grep | awk '{print $2}' | xargs kill -9 mv $JARFILE backup/$JARFILE$DATE mv -f /root/Jenkins-in/$JARFILE . java -jar $JARFILE > out.log & if [ $? = 0 ];then        sleep 30        tail -n 50 out.log fi cd backup/ ls -lt|awk 'NR>5{print $NF}'|xargs rm -rf</code></pre>
  • Apache Shiro教程,您的第一个Apache Shiro应用程序(翻译)

    Apache Shiro教程,您的第一个Apache Shiro应用程序(翻译)-编程技术<h2>您的第一个Apache Shiro应用程序</h2> <p>如果你是Apache Shiro的新手,这个简短的教程将告诉你如何设置一个由Apache Shiro保护的初始和非常简单的应用程序。我们将讨论Shiro的核心概念,以帮助您熟悉Shiro的设计和API。</p> <p>如果您不想按照本教程实际编辑文件,则可以获取几乎相同的示例应用程序,并在您参考时进行参考。选择地点:</p> <ul> <li>在Apache Shiro的Git存储库中:https://github.com/apache/shiro/tree/master/samples/quickstart</li> <li>在Apache Shiro的源代码发布的<code>samples/quickstart</code>目录中。源分发可从下载页面获取。</li> </ul> <h3>建立</h3> <p>在这个简单的例子中,我们将创建一个非常简单的命令行应用程序,它将运行并快速退出,这样您可以感受到Shiro的API。</p>  <strong>任何应用程序</strong> <hr /> <p>Apache Shiro是从第一天开始设计的,以支持<em>任何应用</em>程序 - 从最小的命令行应用程序到最大的集群Web应用程序。即使我们为本教程创建了一个简单的应用程序,也知道无论应用程序如何创建或部署在其中,都会使用相同的使用模式。</p> <p>本教程需要Java 1.5或更高版本。我们还将使用Apache Maven作为我们的构建工具,但是当然这不需要使用Apache Shiro。您可以购买Shiro的.jars并以任何你喜欢的方式将它们合并到应用程序中,例如使用Apache Ant和Ivy。</p> <p>对于本教程,请确保您使用的是Maven 2.2.1或更高版本。您应该能够<code>mvn --version</code>在命令提示符中键入,并看到类似于以下内容:</p> <p><strong>测试Maven安装</strong></p> <pre> <code>hazlewood:~/shiro-tutorial$ mvn --version Apache Maven 2.2.1 (r801777; 2009-08-06 12:16:01-0700) Java version: 1.6.0_24 Java home: /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home Default locale: en_US, platform encoding: MacRoman OS name: "mac os x" version: "10.6.7" arch: "x86_64" Family: "mac" </code></pre> <p>现在,在文件系统上创建一个新目录,例如,<strong><code>shiro-tutorial</code></strong>并将以下Maven <strong><code>pom.xml</code></strong>文件保存在该目录中:</p> <p><strong>pom.xml</strong></p> <pre> <code class="language-xml"><?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.apache.shiro.tutorials</groupId> <artifactId>shiro-tutorial</artifactId> <version>1.0.0-SNAPSHOT</version> <name>First Apache Shiro Application</name> <packaging>jar</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.0.2</version> <configuration> <source>1.5</source> <target>1.5</target> <encoding>${project.build.sourceEncoding}</encoding> </configuration> </plugin> <!-- This plugin is only to test run our little application. It is not needed in most Shiro-enabled applications: --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.1</version> <executions> <execution> <goals> <goal>java</goal> </goals> </execution> </executions> <configuration> <classpathScope>test</classpathScope> <mainClass>Tutorial</mainClass> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.1.0</version> </dependency> <!-- Shiro uses SLF4J for logging. We'll use the 'simple' binding in this example app. See http://www.slf4j.org for more info. --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>1.6.1</version> <scope>test</scope> </dependency> </dependencies> </project> </code></pre> <h4>Tutorial类</h4> <p>我们将运行一个简单的命令行应用程序,因此我们需要使用一个<code>public static void main(String[] args)</code>方法创建一个Java类。</p> <p>在包含您的<code>pom.xml</code>文件的同一目录中,创建一个* <code>src/main/java</code>子目录。在<code>src/main/java</code>创建一个<code>Tutorial.java</code>包含以下内容的文件:</p> <p><strong>src / main / java / Tutorial.java</strong></p> <pre> <code class="language-java">import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.*; import org.apache.shiro.config.IniSecurityManagerFactory; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.session.Session; import org.apache.shiro.subject.Subject; import org.apache.shiro.util.Factory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Tutorial { private static final transient Logger log = LoggerFactory.getLogger(Tutorial.class); public static void main(String[] args) { log.info("My First Apache Shiro Application"); System.exit(0); } } </code></pre> <p>不要担心import语句现在 - 我们会很快得到他们。但是现在,我们有一个典型的命令行程序“shell”。所有这个程序都会打印出文字“我的第一个Apache Shiro应用程序”并退出。</p> <h3>测试运行</h3> <p>要尝试我们的Tutorial应用程序,请在教程项目的根目录(例如<code>shiro-tutorial</code>)中的命令提示符中执行以下命令,然后键入以下内容:</p> <p><code>mvn compile exec:java</code></p> <p>你会看到我们的小教程'应用程序'运行和退出。您应该看到类似以下内容(注意粗体文本,表示我们的输出):</p> <p><strong>运行应用程序</strong></p> <code>lhazlewood:~/projects/shiro-tutorial$ mvn compile exec:java<br /> <br /> ... a bunch of Maven output ...<br /> <br /> <strong>1 [Tutorial.main()] INFO Tutorial - My First Apache Shiro Application</strong><br /> lhazlewood:~/projects/shiro-tutorial\$</code> <p>我们已经验证应用程序运行成功 - 现在让我们启用Apache Shiro。当我们继续教程,你可以运行<code>mvn compile exec:java</code>后,每次我们添加一些更多的代码,以查看我们的更改的结果。</p> <h3>启用S​​hiro</h3> <p>在应用程序中启用Shiro时,首先要了解的是,Shiro中的几乎所有内容都与称为的中央/核心组件相关<code>SecurityManager</code>。对于那些熟悉Java安全性的人,这是Shiro的一个SecurityManager的概念 - 它<em>不是</em>一样的东西<code>java.lang.SecurityManager</code>。</p> <p>虽然我们将在“ 架构”章节中详细介绍Shiro的设计,但现在已经足够了解Shiro <code>SecurityManager</code>是应用程序的Shiro环境的核心,而且每个应用程序<code>SecurityManager</code>都必须存在。因此,我们在Tutorial应用程序中必须做的第一件事是设置<code>SecurityManager</code>实例。</p> <h4>组态</h4> <p>虽然我们可以<code>SecurityManager</code>直接实例化一个类,但是Shiro的<code>SecurityManager</code>实现有足够的配置选项和内部组件,这使得在Java源代码中做这件事变得很困难 - <code>SecurityManager</code>使用灵活的基于文本的配置格式配置更容易。</p> <p>为此,Shiro通过基于文本的INI配置提供了默认的“公分母”解决方案。人们对这些天使用庞大的XML文件感到厌烦,INI很容易阅读,使用简单,而且只需要非常少的依赖。稍后还会看到,通过对对象图形导航的简单理解,INI可以有效地用于配置简单对象图形,如SecurityManager。</p>  <strong>许多配置选项</strong> <hr /> <p>Shiro的<code>SecurityManager</code>实现和所有支持组件都是JavaBeans兼容的。这允许Shiro几乎配置任何配置格式,如XML(Spring,JBoss,Guice等),YAML,JSON,Groovy Builder标记等。INI只是Shiro的“公分母”格式,允许在任何环境中进行配置,以防其他选项不可用。</p>   <h5>shiro.ini</h5> <p>因此,我们将使用一个INI文件来<code>SecurityManager</code>为这个简单的应用程序配置Shiro 。首先,创建一个<strong><code>src/main/resources</code></strong>目录,从同一目录开始,其中<code>pom.xml</code>。然后<code>shiro.ini</code>在该新目录中创建具有以下内容的文件:</p> <p><strong>src / main / resources / shiro.ini</strong></p> <pre> <code># ============================================================================= # Tutorial INI configuration # # Usernames/passwords are based on the classic Mel Brooks' film "Spaceballs" :) # ============================================================================= # ----------------------------------------------------------------------------- # Users and their (optional) assigned roles # username = password, role1, role2, ..., roleN # ----------------------------------------------------------------------------- [users] root = secret, admin guest = guest, guest presidentskroob = 12345, president darkhelmet = ludicrousspeed, darklord, schwartz lonestarr = vespa, goodguy, schwartz # ----------------------------------------------------------------------------- # Roles with assigned permissions # roleName = perm1, perm2, ..., permN # ----------------------------------------------------------------------------- [roles] admin = * schwartz = lightsaber:* goodguy = winnebago:drive:eagle5 </code></pre> <p>正如你所看到的,这个配置基本上设置了一组小的静态用户帐户,足够用于我们的第一个应用程序。在后面的章节中,您将了解如何使用更复杂的用户数据源,如关系数据库,LDAP和ActiveDirectory等。</p> <h4>引用配置</h4> <p>现在我们已经定义了一个INI文件,我们可以<code>SecurityManager</code>在我们的Tutorial应用程序类中创建该实例。更改<code>main</code>方法以反映以下更新:</p> <pre> <code class="language-java">public static void main(String[] args) { log.info("My First Apache Shiro Application"); //1. Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini"); //2. SecurityManager securityManager = factory.getInstance(); //3. SecurityUtils.setSecurityManager(securityManager); System.exit(0); } </code></pre> <p>我们去 - Shiro在我们的示例应用程序中启用,只添加了3行代码!这是多么容易?</p> <p>随意运行<code>mvn compile exec:java</code>,看到一切仍然运行成功(由于Shiro的默认日志记录调试或更低,你不会看到任何Shiro日志消息 - 如果它启动和运行没有错误,那么你知道一切仍然确定)。</p> <p>这里是上面添加的是做什么:</p> <ol> <li> <p>我们使用Shiro的<code>IniSecurityManagerFactory</code>实现来获取<code>shiro.ini</code>位于类路径根目录的文件。这个实现反映了Shiro对工厂方法设计模式的支持。该<code>classpath:</code>前缀是一个资源的指标,告诉四郎在哪里加载从ini文件(其它前缀,如<code>url:</code>和<code>file:</code>以及支持)。</p> </li> <li> <p>该<code>factory.getInstance()</code>方法被调用,它解析INI文件并返回一个<code>SecurityManager</code>反映配置的实例。</p> </li> <li> <p>在这个简单的示例中,我们将其设置<code>SecurityManager</code>为<em>静态</em>(内存)单例,可通过JVM访问。但请注意,如果您在单个JVM中将有多个启用Shiro的应用程序,这是不可取的。对于这个简单的例子,它是确定,但更复杂的应用程序环境通常会放置<code>SecurityManager</code>在应用程序特定的内存(如在Web应用程序<code>ServletContext</code>或Spring,Guice或JBoss DI容器实例)。</p> </li> </ol> <h3>使用Shiro</h3> <p>现在我们的SecurityManager已经设置好了,现在我们可以开始做我们真正关心的事情 - 执行安全操作。</p> <p>当保护我们的应用程序时,我们可能最相关的问题是“当前用户是谁”或“当前用户是否允许做X”?在我们编写代码或设计用户界面时,常常会提出这些问题:应用程序通常基于用户故事构建,并且您希望基于每个用户表示(和安全)的功能。因此,我们在应用程序中考虑安全性的最自然的方式是基于当前用户。Shiro的API从根本上代表了“当前用户”的<code>Subject</code>概念。</p> <p>在几乎所有环境中,您可以通过以下调用获取当前正在执行的用户:</p> <pre> <code>Subject currentUser = SecurityUtils.getSubject(); </code></pre> <p>使用<code>SecurityUtils</code>。getSubject(),我们可以获取当前正在执行的<code>Subject</code>。<em>主题</em>是一个安全术语,基本上意味着“当前正在执行的用户的安全特定视图”。它不被称为“用户”,因为“用户”这个词通常与一个人相关联。在安全世界中,术语“主题”可以指人,也可以是第三方进程,cron作业,守护进程帐户或任何类似的。它只是指“当前与软件交互的东西”。对于大多数意图和目的,你可以认为<code>Subject</code>是Shiro的'用户'概念。</p> <p>独立应用程序中的<code>getSubject()</code>调用可以<code>Subject</code>基于应用程序特定位置中的用户数据返回,并且在服务器环境(例如web应用程序)中,它<code>Subject</code>基于与当前线程或传入请求相关联的用户数据来获取。</p> <p>现在你有了<code>Subject</code>,你能用它做什么?</p> <p>如果您想在用户在应用程序的当前会话期间使用户可用,您可以获取其会话:</p> <pre> <code>Session session = currentUser.getSession(); session.setAttribute( "someKey", "aValue" ); </code></pre> <p>这<code>Session</code>是一个Shiro特定的实例,提供了大多数你习惯了与常规HttpSessions,但有一些额外的好处和一个<strong>巨大的</strong>区别:它不需要HTTP环境!</p> <p>如果在Web应用程序中部署,默认情况下<code>Session</code>将<code>HttpSession</code>基于。但是,在非Web环境中,像这个简单的教程应用程序,Shiro将默认自动使用其企业会话管理。这意味着您可以在任何层次的应用程序中使用相同的API,而不考虑部署环境!这打开了一个全新的应用程序世界,因为任何需要会话的应用程序不需要被强制使用<code>HttpSession</code>或EJB有状态会话Bean。而且,任何客户端技术现在都可以共享会话数据。</p> <p>所以现在你可以获得一个<code>Subject</code>和他们<code>Session</code>。怎么样<em>真正</em>像检查,如果他们被允许做的事情,比如对角色和权限检查有用的东西?</p> <p>好吧,我们只能为已知用户执行这些检查。我们的<code>Subject</code>上面的实例代表当前用户,但<em>谁</em>是当前用户?好吧,他们是匿名的 - 也就是说,直到他们至少登录一次。所以,让我们这样做:</p> <pre> <code class="language-java">if ( !currentUser.isAuthenticated() ) { //collect user principals and credentials in a gui specific manner //such as username/password html form, X509 certificate, OpenID, etc. //We'll use the username/password example here since it is the most common. UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa"); //this is all you have to do to support 'remember me' (no config - built in!): token.setRememberMe(true); currentUser.login(token); } </code></pre> <p>而已!这不容易。</p> <p>但是,如果他们的登录尝试失败怎么办?您可以捕获各种特定的异常,告诉您发生了什么,并允许您处理并做出相应的反应:</p> <pre> <code class="language-java">try { currentUser.login( token ); //if no exception, that's it, we're done! } catch ( UnknownAccountException uae ) { //username wasn't in the system, show them an error message? } catch ( IncorrectCredentialsException ice ) { //password didn't match, try again? } catch ( LockedAccountException lae ) { //account for that username is locked - can't login. Show them a message? } ... more types exceptions to check if you want ... } catch ( AuthenticationException ae ) { //unexpected condition - error? } </code></pre> <p>有很多不同类型的异常,你可以检查,或抛出自己的自定义条件Shiro可能不考虑。有关更多信息,请参阅AuthenticationException JavaDoc。</p>  <strong>方便的提示</strong> <hr /> <p>安全最佳做法是向用户提供通用登录失败消息,因为您不想帮助攻击者试图进入您的系统。</p> <p>好的,所以到现在为止,我们有一个登录用户。我们还能做什么?</p> <p>让我们说他们是谁:</p> <pre> <code>//print their identifying principal (in this case, a username): log.info( "User [" + currentUser.getPrincipal() + "] logged in successfully." ); </code></pre> <p>我们还可以测试他们是否有特定的作用:</p> <pre> <code class="language-java">if ( currentUser.hasRole( "schwartz" ) ) { log.info("May the Schwartz be with you!" ); } else { log.info( "Hello, mere mortal." ); } </code></pre> <p>我们还可以看到他们是否有权对某种类型的实体采取行动:</p> <pre> <code class="language-java">if ( currentUser.isPermitted( "lightsaber:weild" ) ) { log.info("You may use a lightsaber ring. Use it wisely."); } else { log.info("Sorry, lightsaber rings are for schwartz masters only."); } </code></pre> <p>此外,我们可以执行非常强大的<em>实例级</em>权限检查 - 查看用户是否能够访问类型的特定实例:</p> <pre> <code class="language-java">if ( currentUser.isPermitted( "winnebago:drive:eagle5" ) ) { log.info("You are permitted to 'drive' the 'winnebago' with license plate (id) 'eagle5'. " + "Here are the keys - have fun!"); } else { log.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!"); } </code></pre> <p>蛋糕,对吧?</p> <p>最后,当用户完成使用应用程序时,他们可以注销:</p> <pre> <code>currentUser.logout(); //removes all identifying information and invalidates their session too. </code></pre> <h4>最终教程类</h4> <p>在添加上面的代码示例之后,这里是我们最终的Tutorial类文件。随意编辑和玩它,并更改安全检查(和INI配置),你喜欢:</p> <p><strong>最终src / main / java / Tutorial.java</strong></p> <pre> <code class="language-java">import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.*; import org.apache.shiro.config.IniSecurityManagerFactory; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.session.Session; import org.apache.shiro.subject.Subject; import org.apache.shiro.util.Factory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Tutorial { private static final transient Logger log = LoggerFactory.getLogger(Tutorial.class); public static void main(String[] args) { log.info("My First Apache Shiro Application"); Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini"); SecurityManager securityManager = factory.getInstance(); SecurityUtils.setSecurityManager(securityManager); // get the currently executing user: Subject currentUser = SecurityUtils.getSubject(); // Do some stuff with a Session (no need for a web or EJB container!!!) Session session = currentUser.getSession(); session.setAttribute("someKey", "aValue"); String value = (String) session.getAttribute("someKey"); if (value.equals("aValue")) { log.info("Retrieved the correct value! [" + value + "]"); } // let's login the current user so we can check against roles and permissions: if (!currentUser.isAuthenticated()) { UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa"); token.setRememberMe(true); try { currentUser.login(token); } catch (UnknownAccountException uae) { log.info("There is no user with username of " + token.getPrincipal()); } catch (IncorrectCredentialsException ice) { log.info("Password for account " + token.getPrincipal() + " was incorrect!"); } catch (LockedAccountException lae) { log.info("The account for username " + token.getPrincipal() + " is locked. " + "Please contact your administrator to unlock it."); } // ... catch more exceptions here (maybe custom ones specific to your application? catch (AuthenticationException ae) { //unexpected condition? error? } } //say who they are: //print their identifying principal (in this case, a username): log.info("User [" + currentUser.getPrincipal() + "] logged in successfully."); //test a role: if (currentUser.hasRole("schwartz")) { log.info("May the Schwartz be with you!"); } else { log.info("Hello, mere mortal."); } //test a typed permission (not instance-level) if (currentUser.isPermitted("lightsaber:weild")) { log.info("You may use a lightsaber ring. Use it wisely."); } else { log.info("Sorry, lightsaber rings are for schwartz masters only."); } //a (very powerful) Instance Level permission: if (currentUser.isPermitted("winnebago:drive:eagle5")) { log.info("You are permitted to 'drive' the winnebago with license plate (id) 'eagle5'. " + "Here are the keys - have fun!"); } else { log.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!"); } //all done - log out! currentUser.logout(); System.exit(0); } } </code></pre> <h3>概要</h3> <p>希望这个介绍教程帮助你了解如何设置Shiro在一个基本的应用程序,以及Shiro的主要设计概念,<code>Subject</code>和<code>SecurityManager</code>。</p> <p>但这是一个相当简单的应用程序。你可能会问自己,“如果我不想使用INI用户帐户而是想连接到更复杂的用户数据源怎么办?</p> <p>要回答这个问题,需要更深入地了解Shiro的架构和支持配置机制。接下来我们将介绍Shiro的建筑。</p>
  • centos6 redis3.29 安装(yum和源码安装)完整步骤以及常用配置

    centos6 yum安装redis3.29,centos6 源码安装redis以及常用配置<h2>一、 <span style="font-family:宋体">检查</span>yum<span style="font-family:宋体">可以安装的版本</span></h2> <h3>1.1<span style="font-family:宋体">查看当前系统可以安装的</span>redis<span style="font-family:宋体">版本</span></h3> <p><span style="font-family:宋体">命令</span>:</p> <p><strong>[root@localhost ~]# yum list|grep redis</strong></p> <p>[root@localhost ~]#</p> <p> </p> <p><span style="font-family:宋体">发现没有可以安装的</span>,<span style="font-family:宋体">如果有则忽略下面的步骤</span></p> <h3>1.2<span style="font-family:宋体">安装</span>centos<span style="font-family:宋体">提供的</span>epel-release<span style="font-family:宋体">源</span></h3> <p><span style="font-family:宋体">命令</span>:</p> <pre> <code class="language-java">[root@localhost ~]# yum install epel-release</code></pre> <p><img alt="1" class="img-thumbnail" src="/assist/images/blog/a4ba199bfd204d84bbdd4bac341c08aa.png" /></p> <p><span style="font-family:宋体">安装好以后再次查看可以安装的</span>redis<span style="font-family:宋体">版本</span></p> <p><span style="font-family:宋体">命令</span>:</p> <pre> <code class="language-java">[root@localhost ~]# yum list|grep redis php-nrk-Predis.noarch                       0.8.6-1.el6                  epel   php-pecl-redis.x86_64                       2.2.8-1.el6                  epel   php-redis.x86_64                            2.2.2-5.git6f7087f.el6       epel   python-redis.noarch                         2.0.0-1.el6                  epel   redis.x86_64                                2.4.10-1.el6                 epel   uwsgi-logger-redis.x86_64                   2.0.15-1.el6                 epel   uwsgi-router-redis.x86_64                   2.0.15-1.el6                 epel   [root@localhost ~]#</code></pre> <p><span style="font-family:宋体">现在有了可以安装的版本了。但是版本还是太低是</span>2.4<span style="font-family:宋体">的版本。</span></p> <p><span style="font-family:宋体">结论</span>:CentOS6<span style="font-family:宋体">不能直接通过</span>yum<span style="font-family:宋体">安装</span>redis3.X<span style="font-family:宋体">版本。需要源码安装</span>,centos7<span style="font-family:宋体">则可以。具体安装方式可根据使用的系统版本来抉择。</span></p> <p> </p> <h2 style="margin-left:36.0pt">二、 <span style="font-family:宋体">获取</span>redis<span style="font-family:宋体">安装资源以及环境</span></h2> <h3>2.1<span style="font-family:宋体">下载</span>redis<span style="font-family:宋体">的安装文件包</span></h3> <p><span style="font-family:宋体">官网地址</span>: <a href="https://redis.io/download" rel="external nofollow" target="_blank">https://redis.io/download</a></p> <p>Redis 3.2.9<span style="font-family:宋体">下载地址</span>: <a href="http://download.redis.io/releases/redis-3.2.9.tar.gz" rel="external nofollow" target="_blank">http://download.redis.io/releases/redis-3.2.9.tar.gz</a></p> <p> </p> <p><span style="font-family:宋体">直接下载命令</span>:</p> <pre> <code class="language-java">[root@localhost ~]# wget http://download.redis.io/releases/redis-3.2.9.tar.gz</code></pre> <p><span style="font-family:宋体">下载完成后在当前目录会有</span>redis-3.2.9.tar.gz<span style="font-family:宋体">包</span></p> <p><img alt="2" class="img-thumbnail" src="/assist/images/blog/72c50fea69174343b711b862b7c7a1d2.png" /></p> <p> </p> <h3>2.2<span style="font-family:宋体">检查</span>gcc<span style="font-family:宋体">环境</span></h3> <p><span style="font-family:宋体">检查系统中是否有</span>gcc<span style="font-family:宋体">编译器</span>,<span style="font-family:宋体">因为源码安装需要使用</span>gcc<span style="font-family:宋体">编译</span></p> <p><span style="font-family:宋体">命令</span>:</p> <pre> <code class="language-java">[root@localhost ~]# rpm -qa|grep gcc gcc-4.4.7-4.el6.x86_64 libgcc-4.4.7-4.el6.x86_64 [root@localhost ~]#</code></pre> <p><span style="font-family:宋体">上面的命令执行结果标识系统已经安装有</span>gcc<span style="font-family:宋体">编译器</span>,<span style="font-family:宋体">如果没有则执行下面的命令</span>,<span style="font-family:宋体">有则忽略下面步骤</span></p> <p><span style="font-family:宋体">安装</span>GCC<span style="font-family:宋体">命令</span></p> <pre> <code>[root@localhost ~]# yum install –y gcc</code></pre> <p> </p> <h2><span style="font-family:宋体">三、安装</span>redis</h2> <h3>3.1<span style="font-family:宋体">创建</span>redis<span style="font-family:宋体">安装目录</span></h3> <p><span style="font-family:宋体">命令</span>:</p> <pre> <code class="language-java">[root@localhost ~]# mkdir -p /usr/local/redis-3.2.9 [root@localhost ~]#</code></pre> <h3>3.2<span style="font-family:宋体">解压下载的</span>redis<span style="font-family:宋体">安装文件</span></h3> <p><span style="font-family:宋体">命令</span>:</p> <pre> <code class="language-java">[root@localhost ~]# tar -xzvf redis-3.2.9.tar.gz</code></pre> <h3>3.3<span style="font-family:宋体">指定安装目录安装</span>redis</h3> <p><span style="font-family:宋体">首先进入解压后的</span>redis<span style="font-family:宋体">目录</span></p> <p><span style="font-family:宋体">命令</span>:</p> <pre> <code class="language-java">[root@localhost ~]# cd redis-3.2.9 [root@localhost redis-3.2.9]#</code></pre> <p><span style="font-family:宋体">指定目录安装</span>redis</p> <p><span style="font-family:宋体">命令</span>:</p> <pre> <code class="language-java">[root@localhost redis-3.2.9]#make PREFIX=/usr/local/redis-3.2.9 install</code></pre> <p><img alt="3" class="img-thumbnail" src="/assist/images/blog/dc50ab10f63249c8ad7ae52bd5a5137d.png" /></p> <h3>3.4<span style="font-family:宋体">创建一个软连接方便访问寻找</span></h3> <p><span style="font-family:宋体">命令</span>:</p> <pre> <code class="language-java">ln -s /usr/local/redis-3.2.9 /usr/local/redis</code></pre> <p> </p> <h2><span style="font-family:宋体">四、配置</span>redis</h2> <h3>4.1<span style="font-family:宋体">添加配置文件到</span>/etc<span style="font-family:宋体">目录</span></h3> <p><span style="font-family:宋体">默认的</span>redis<span style="font-family:宋体">配置文件还在刚才解压的文件目录中</span>,<span style="font-family:宋体">在</span>Linux<span style="font-family:宋体">系统使用中,通常把配置的文件放在</span>/etc<span style="font-family:宋体">目录下。算一个规范。</span></p> <p> </p> <p><span style="font-family:宋体">将源码目录下的</span>redis<span style="font-family:宋体">配置文件添加一份到</span>/etc<span style="font-family:宋体">目录下</span></p> <p><span style="font-family:宋体">命令</span>:</p> <pre> <code class="language-java">[root@localhost redis-3.2.9]# pwd /root/redis-3.2.9 [root@localhost redis-3.2.9]# ll redis.conf -rw-rw-r--. 1 root root 46695 May 17 08:39 redis.conf [root@localhost redis-3.2.9]# cp redis.conf /etc/redis.conf</code></pre> <h3>4.2.<span style="font-family:宋体">修改</span>redis<span style="font-family:宋体">默认以后台进程方式启动</span></h3> <p><span style="font-family:宋体">编辑</span>/etc/redis.conf<span style="font-family:宋体">配置</span>redis<span style="font-family:宋体">以后台方式启动</span></p> <pre> <code class="language-java">[root@localhost redis-3.2.9]# vi /etc/redis.conf</code></pre> <p><img alt="4" class="img-thumbnail" src="/assist/images/blog/a9e3c8b8406a45f58c4eee2f385a35e4.png" /></p> <p><span style="font-family:宋体">在文件中找到</span>daemonize<span style="font-family:宋体">配置</span>,<span style="font-family:宋体">默认是</span>no,<span style="font-family:宋体">修改成</span>yes</p> <p><img alt="5" class="img-thumbnail" src="/assist/images/blog/f498bccd0e494038a896ce370945ced0.png" /></p> <p><span style="color:#e74c3c"><strong><span style="font-family:宋体">提示</span>:</strong><em><span style="font-family:宋体">配置文件配置项后面不要有空格</span></em></span></p> <p> </p> <h3>4.3<span style="font-family:宋体">配置</span>redis<span style="font-family:宋体">允许远程访问</span></h3> <p><span style="font-family:宋体">编辑</span>/etc/redis.conf<span style="font-family:宋体">配置</span>redis<span style="font-family:宋体">允许远程访问</span></p> <pre> <code class="language-java">[root@localhost redis-3.2.9]# vi /etc/redis.conf</code></pre> <p><img alt="6" class="img-thumbnail" src="/assist/images/blog/5ac5d3d3ca214782b9a76513b1cde8fc.png" /></p> <p><span style="font-family:宋体">将</span>bind 127.0.0.1<span style="font-family:宋体">注释掉即可随意访问,如果不注释则只能通过bind后面的ip进行访问。如:</span><br />  </p> <pre> <code>bind 127.0.0.1 192.168.1.3</code></pre> <p><span style="color:#e74c3c"><strong>上面的配置标识只能本地或者访问自己的ip地址192.168.1.3进行访问</strong></span><br /> <br /> 为了测试方便,注释掉即可。生产请bind自己主机的局域网IP地址<br /> <br /> <img alt="7" class="img-thumbnail" src="/assist/images/blog/3608e0016dc647e08bfa2c0fe5c4ac00.png" /></p> <p><span style="font-family:宋体">但是远程访问还不能读写</span>,<span style="font-family:宋体">所以继续配置</span></p> <p><span style="font-family:宋体">找到</span>protected-mode yes(<span style="color:#8e44ad"><strong>如果使用bind的方式则不需要修改</strong></span>)</p> <p><img alt="8" class="img-thumbnail" src="/assist/images/blog/0d331967cc774469a18bfbc4e41afaf8.png" /></p> <p><span style="font-family:宋体">修改为</span>protected-mode no</p> <p><img alt="9" class="img-thumbnail" src="/assist/images/blog/50f6d50040ee4b29bf59e28ca86992f2.png" /></p> <p> </p> <h3>4.4<span style="font-family:宋体">配置</span>redis<span style="font-family:宋体">访问密码</span></h3> <p><span style="font-family:宋体">编辑</span>/etc/redis.conf<span style="font-family:宋体">配置</span>redis<span style="font-family:宋体">设置访问密码</span></p> <p><span style="font-family:宋体">找到配置文件中的</span><span style="background-color:white"><span style="font-family:Consolas"><span style="color:black">requirepass</span></span></span><span style="background-color:white"><span style="font-family:宋体"><span style="color:black">配置</span></span></span></p> <p><img alt="10" class="img-thumbnail" src="/assist/images/blog/f1c0f305ea6f4d7b8ef3601467340781.png" /></p> <p><span style="font-family:宋体">默认情况是注释的</span>,<span style="font-family:宋体">配置的</span><span style="background-color:white"><span style="font-family:Consolas"><span style="color:black">requirepass </span></span></span><span style="background-color:white"><span style="font-family:宋体"><span style="color:black">后面跟的</span></span></span><span style="background-color:white"><span style="font-family:Consolas"><span style="color:black">foobared</span></span></span><span style="background-color:white"><span style="font-family:宋体"><span style="color:black">就是密码</span></span></span></p> <p><span style="background-color:white"><span style="font-family:宋体"><span style="color:black">例如现在启用密码</span></span></span><span style="background-color:white"><span style="font-family:Consolas"><span style="color:black">,</span></span></span><span style="background-color:white"><span style="font-family:宋体"><span style="color:black">并且将密码设置为</span></span></span><span style="background-color:white"><span style="font-family:Consolas"><span style="color:black">123456</span></span></span><span style="background-color:white"><span style="font-family:宋体"><span style="color:black">,则配置为</span></span></span><span style="background-color:white"><span style="font-family:Consolas"><span style="color:black">:</span></span></span></p> <p><img alt="11" class="img-thumbnail" src="/assist/images/blog/c39435d76b21443f8043f387536d662e.png" /></p> <p><span style="font-family:宋体">去掉</span>#<span style="font-family:宋体">并将后面的密码修改为</span>123456</p> <p><span style="color:#e74c3c"><strong><span style="font-family:宋体">提示</span></strong><em>:</em><em><span style="font-family:宋体">配置前后不要留空格</span></em></span><br />  </p> <span style="font-family:宋体">配置redis最大使用内存以及超出最大内存后的处理策略</span><br />   <p><strong>#maxmemory </strong><strong><bytes></strong></p> <p>redis-cache所能使用的最大内存(bytes),默认为0,表示"无限制",最终由OS物理内存大小决定(如果物理内存不足,有可能会使用swap)。此值尽量不要超过机器的物理内存尺寸,从性能和实施的角度考虑,可以为物理内存3/4。此配置需要和"maxmemory-policy"配合使用,当redis中内存数据达到maxmemory时,触发"清除策略"。在"内存不足"时,任何write操作(比如set,lpush等)都会触发"清除策略"的执行。在实际环境中,建议redis的所有物理机器的硬件配置保持一致(内存一致),同时确保master/slave中"maxmemory""policy"配置一致。</p> <p>当内存满了的时候,如果还接收到set 命令,redis 将先尝试剔除设置过expire 信息的key,而不管该key 的过期时间还没有到达。在删除时,</p> <p>将按照过期时间进行删除,最早将要被过期的key 将最先被删除。如果带有expire 信息的key 都删光了,内存还不够用,那么将返回错误。这样,redis 将不再接收写请求,只接收get 请求。maxmemory 的设置比较适合于把redis 当作于类似memcached的缓存来使用。</p> <p><strong># maxmemory-policy noeviction</strong></p> <p>内存不足"时,数据清除策略,默认为"noeviction。</p> <p><em>volatile-lru</em>  ->对"过期集合"中的数据采取LRU(近期最少使用)算法.如果对key使用"expire"指令指定了过期时间,那么此key将会被添加到"过期集合"中。将已经过期/LRU的数据优先移除.如果"过期集合"中全部移除仍不能满足内存需求,将OOM.<br /> <em>allkeys-lru</em> ->对所有的数据,采用LRU算法<br /> <em>volatile-random</em> ->对"过期集合"中的数据采取"随即选取"算法,并移除选中的K-V,直到"内存足够"为止. 如果如果"过期集合"中全部移除全部移除仍不能满足,将OOM<br /> <em>allkeys-random</em> ->对所有的数据,采取"随机选取"算法,并移除选中的K-V,直到"内存足够"为止<br /> <em>volatile-ttl</em> ->对"过期集合"中的数据采取TTL算法(最小存活时间),移除即将过期的数据.<br /> <em>noeviction</em> ->不做任何干扰操作,直接返回OOM异常<br /> 另外,如果数据的过期不会对"应用系统"带来异常,且系统中write操作比较密集,建议采取"allkeys-lru"<br /> <br /> <strong>举个栗子:</strong><br /> 配置最大使用内存2GB,超出后对不常使用的缓存清理,快过期缓存清理的配置为:</p> <pre> <code>#设置默认内存大小3GB maxmemory 3GB #设置清楚策略allkeys-lru maxmemory-policy allkeys-lru</code></pre> <h3>4.5<span style="font-family:宋体">创建</span>redis<span style="font-family:宋体">用户</span></h3> <p><span style="font-family:宋体">命令</span>:</p> <pre> <code class="language-java"># useradd -r -s /sbin/nologin -M redis</code></pre> <p>4.6<span style="font-family:宋体">创建</span>redis<span style="font-family:宋体">启动弄脚本便于使用</span>service<span style="font-family:宋体">管理</span>redis</p> <p><strong><span style="font-family:宋体">命令</span>:</strong></p> <pre> <code class="language-java">#vi  /etc/init.d/redis</code></pre> <p><span style="font-family:宋体">脚本内容</span>:<br />  </p> <pre> <code class="language-bash">#!/bin/bash #chkconfig: 2345 55 25 #description: Starts,stops and restart the redis-server #Ver:1.1  #Write by ND chengh(200808) #usage: ./script_name -p [port] {start|stop|status|restart} # Source function library. . /etc/rc.d/init.d/functions # Source networking configuration. . /etc/sysconfig/network # Check networking is up. [ "$NETWORKING" = "no" ] && exit 0 RETVAL=0 REDIS_PORT=6379 PID= if [ "$1" = "-p" ]; then     REDIS_PORT=$2     shift 2 fi REDIS_DIR="/usr/local/redis" REDIS_CONF_DIR="/etc" REDIS="${REDIS_DIR}/bin/redis-server" PROG=$(basename $REDIS) CONF="${REDIS_CONF_DIR}/redis-${REDIS_PORT}.conf" if [ ! -f $CONF ]; then    if [ -f "${REDIS_CONF_DIR}/redis.conf" ];then       CONF="${REDIS_CONF_DIR}/redis.conf"    else       echo -n $"$CONF not exist.";warning;echo       exit 1    fi fi PID_FILE=`grep "pidfile" ${CONF}|cut -d ' ' -f2` PID_FILE=${PID_FILE:=/var/run/redis.pid} LOCKFILE="/var/lock/subsys/redis-${REDIS_PORT}" if [ ! -x $REDIS ]; then     echo -n $"$REDIS not exist.";warning;echo     exit 0 fi start() {     echo -n $"Starting $PROG: "     $REDIS $CONF     RETVAL=$?     if [ $RETVAL -eq 0 ]; then         success;echo;touch $LOCKFILE     else         failure;echo     fi     return $RETVAL } stop() {     echo -n $"Stopping $PROG: "     if [ -f $PID_FILE ] ;then        read PID <  "$PID_FILE"     else        failure;echo;        echo -n $"$PID_FILE not found.";failure;echo        return 1;     fi     if checkpid $PID; then      kill -TERM $PID >/dev/null 2>&1         RETVAL=$?         if [ $RETVAL -eq 0 ] ;then                 success;echo                 echo -n "Waiting for Redis to shutdown .."          while checkpid $PID;do                  echo -n "."                  sleep 1;                 done                 success;echo;rm -f $LOCKFILE         else                 failure;echo         fi     else         echo -n $"Redis is dead and $PID_FILE exists.";failure;echo         RETVAL=7     fi        return $RETVAL } restart() {     stop     start } rhstatus() {     status -p ${PID_FILE} $PROG } hid_status() {     rhstatus >/dev/null 2>&1 } case "$1" in     start)         hid_status && exit 0         start         ;;     stop)         rhstatus || exit 0         stop         ;;     restart)         restart         ;;     status)         rhstatus         RETVAL=$?         ;;     *)         echo $"Usage: $0 -p [port] {start|stop|status|restart}"         RETVAL=1 esac exit $RETVAL </code></pre> <p><span style="background-color:#fafafc"><span style="font-family:宋体"><span style="color:#333333">上面脚本中可根据具体</span></span></span><span style="background-color:#fafafc"><span style="font-family:"Tahoma",sans-serif"><span style="color:#333333">redis</span></span></span><span style="background-color:#fafafc"><span style="font-family:宋体"><span style="color:#333333">安装位置配置</span></span></span><span style="background-color:#fafafc"><span style="font-family:"Tahoma",sans-serif"><span style="color:#333333">redis-server</span></span></span><span style="background-color:#fafafc"><span style="font-family:宋体"><span style="color:#333333">的路径和</span></span></span><span style="background-color:#fafafc"><span style="font-family:"Tahoma",sans-serif"><span style="color:#333333">conf</span></span></span><span style="background-color:#fafafc"><span style="font-family:宋体"><span style="color:#333333">的路径</span></span></span></p> <p><span style="background-color:#fafafc"><span style="font-family:"Tahoma",sans-serif"><span style="color:#333333">redis</span></span></span><span style="background-color:#fafafc"><span style="font-family:宋体"><span style="color:#333333">默认安装在</span></span></span></p> <p><span style="background-color:#fafafc"><span style="font-family:"Tahoma",sans-serif"><span style="color:#333333">/usr/local/redis</span></span></span><span style="background-color:#fafafc"><span style="font-family:宋体"><span style="color:#333333">目录下</span></span></span></p> <p><span style="background-color:#fafafc"><span style="font-family:"Tahoma",sans-serif"><span style="color:#333333">Redis</span></span></span><span style="background-color:#fafafc"><span style="font-family:宋体"><span style="color:#333333">配置文件存放在</span></span></span></p> <p><span style="background-color:#fafafc"><span style="font-family:"Tahoma",sans-serif"><span style="color:#333333">/etc/redis.conf</span></span></span></p> <p> </p> <p><span style="background-color:#fafafc"><span style="font-family:宋体"><span style="color:#333333">修改脚本权限</span></span></span></p> <pre> <code class="language-java">#chmod 755 /etc/init.d/redis</code></pre> <p> </p> <p><span style="font-family:宋体">添加进</span>service<span style="font-family:宋体">管理</span></p> <pre> <code class="language-java">#chkconfig --add redis</code></pre> <p> </p> <p><span style="font-family:宋体">设置开机启动</span></p> <pre> <code class="language-java"># chkconfig redis on</code></pre> <p>4.7<span style="font-family:宋体">启动</span>redis</p> <pre> <code class="language-java">[root@localhost redis-3.2.9]# service redis start Starting redis-server:                                     [  OK  ]</code></pre> <p><img alt="12" class="img-thumbnail" src="/assist/images/blog/3c9b6e9d57104e82a82649a844c5b1d8.png" /></p> <p> </p> <h2><span style="font-family:宋体">五、连接到</span>redis<span style="font-family:宋体">测试</span></h2> <p><span style="font-family:宋体">连接命令</span>:</p> <pre> <code class="language-java">#/usr/local/redis/bin/redis-cli -h 127.0.0.1 -p 6379</code></pre> <p> </p> <p><span style="font-family:宋体">设置一个值</span>:</p> <pre> <code>127.0.0.1:6379> set testKey testValue</code></pre> <p><img alt="13" class="img-thumbnail" src="/assist/images/blog/963b924d72964889b49019bfa0695e2d.png" /></p> <p><span style="font-family:宋体">获取上面的设置值</span></p> <p><span style="font-family:宋体">命令</span>:</p> <pre> <code>127.0.0.1:6379> get testKey</code></pre> <p><img alt="14" class="img-thumbnail" src="/assist/images/blog/82deb7d506ea4673970ad757e8f5492c.png" /></p> <p>删除上面的值<br /> 命令</p> <pre> <code>del testKey</code></pre> <p><br />  </p>