分类目录归档:Apache

利用Apache htaccess文件创建密码保护网站隐私目录

在生产环境中,各种各样的网站目录限制场景非常之多,这时就可能需要用到Apache htpasswd工具来实现,下面我将一一讲解如何使用。

先使用Apache htpasswd命令创建一个密码文件,htpasswd的命令用法如下:

-c # 创建密码文件,若该文件已存在,它会重写并删除原有内容;
-n # 不更新密码文件,直接显示密码;
-m # 使用MD5加密(默认);
-d # 使用CRYPT加密(默认);
-p # 使用普通文本格式的密码;
-s # 使用SHA加密;
-b # 命令行中一并输入用户和密码,而交互性,生成时可见密码明文;
-D # 删除指定的用户;

创建添加一个用户名为:renwole 密码为:renwole 的密码文件:

$ htpasswd -c .accpasswd renwole
New password:
Re-type new password:
Adding password for user renwole

注意:创建的密码 .accpasswd 文件名可自定义。

使用cat查看生成的内容:

$ cat .accpasswd
renwole:$apr1$4owQhqtn$ElCDIh0sfR.ZFzeaY9sDw0

注意:生成的密码是已经加密过的,所以别弄混掉了。

添加多个账号:

$ htpasswd -b .accpasswd renwolecom password-renwolecom
Adding password for user renwolecom

查看生成的多个账号和密码:

$ cat .accpasswd
renwole:$apr1$4owQhqtn$ElCDIh0sfR.ZFzeaY9sDw0
renwolecom:$apr1$3zzGmKtR$jKKCbU2nVEQZFz9mtEXE./

删除用户:

$ htpasswd -D .accpasswd renwolecom
Deleting password for user renwolecom

查看删除后的密码文件:

$ cat .accpasswd
renwole:$apr1$4owQhqtn$ElCDIh0sfR.ZFzeaY9sDw0

创建密码保护区域

有了密码文件之后,我们可以使用.htaccess文件创建保护区域。

将以下内容保存为 .htaccess 文件,这样我们就可以使用该文件建立保护区域。

$ vim /apps/web/renwolecom/phpMyadmin/.htaccess

AuthType Basic
AuthName "restricted area"
AuthUserFile /usr/local/apache/conf/.accpasswd
require valid-user

将该文件放在需要保护的目录下即可。因此我放在了网站根目录的phpMyadmin目录,这样访问此目录,就会出现弹窗验证,输入生成的用户名和密码即可。

Centos 7源代码安装配置 Apache 生产篇

什么是Apache?

Apache是​​互联网上最流行的网络web服务器。全球一半以上网站都是使用Apache作为服务器。其也是一个工业级的 Web服务器。

在本文中我主要介绍如何安装Apache HTTP服务器,你只要按照本教程的步骤操作,一定可以安装成功,需要说明的是,如果你只安装Apache,而不安装php,请在配置文件中,删除 FilesMatch 包含的内容,否则会报错找不到PHP。

如果你需要安装PHP/Mysql数据库,那么本站教程太适合你了,关于php和mysql的安装,请阅读:11、12步骤。

说明:本文教程适用于生产环境,Apache是基于FPM/FastCGI解析的PHP。

系统环境:Centos 7.4 Apache 2.4.29

1.更新系统

$ yum update && yum upgrade -y

2.安装扩展包以及依赖包

$ yum install epel-release -y
$ yum install gcc gcc-c++ openssl openssl-devel libtool expat-devel zlib-devel python-devel -y

3.安装pcre

$ wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.41.tar.gz
$ tar zxvf pcre-8.41.tar.gz
$ cd pcre-8.41
$ ./configure
$ make -j8 && make install

4.安装nghttp2

$ wget //github.com/nghttp2/nghttp2/releases/download/v1.27.0/nghttp2-1.27.0.tar.gz
$ tar zxvf nghttp2-1.27.0.tar.gz
$ cd nghttp2-1.27.0
$ ./configure
$ make -j8 && make install
$ echo '/usr/local/lib' > /etc/ld.so.conf.d/local.conf
$ ldconfig

5.安装Apache httpd

创建用户与组并下载httpd apr apr-util安装包:

$ groupadd www
$ useradd -g www www
$ cd /tmp
$ wget //mirrors.shuosc.org/apache//httpd/httpd-2.4.29.tar.gz
$ wget //mirrors.tuna.tsinghua.edu.cn/apache//apr/apr-1.6.3.tar.gz
$ wget //mirrors.tuna.tsinghua.edu.cn/apache//apr/apr-util-1.6.1.tar.gz

解压相关包:

$ tar xvf httpd-2.4.29.tar.gz
$ tar xvf apr-1.6.3.tar.gz
$ tar xvf apr-util-1.6.1.tar.gz

apr-1.6.3apr-util-1.6.1移动到httpd-2.4.29/srclib目录下。操作如下:

$ cd httpd-2.4.29
$ cp -R ../apr-1.6.3 srclib/apr
$ cp -R ../apr-util-1.6.1 srclib/apr-util

注意:移动不准带版本号,否则编译安装时找不到库。

开始安装:

$ ./configure \
--prefix=/usr/local/apache \
--enable-mods-shared=most \
--enable-headers \
--enable-mime-magic \
--enable-proxy \
--enable-so \
--enable-rewrite \
--with-ssl \
--with-nghttp2 \
--enable-ssl \
--enable-deflate \
--with-pcre \
--with-included-apr \
--with-apr-util \
--enable-mpms-shared=all \
--with-mpm=prefork \
--enable-remoteip \
--enable-http2 \
--enable-dav \
--enable-expires \
--enable-static-support \
--enable-suexec \
--enable-modules=all \
$ make -j8 && make install

安装完成。

6.配置httpd.conf

$ cd /usr/local/apache/conf
$ vim httpd.conf

除默认配置外,请取消以下注释,开启相关模块:

LoadModule ext_filter_module modules/mod_ext_filter.so
LoadModule deflate_module modules/mod_deflate.so
LoadModule expires_module modules/mod_expires.so
LoadModule remoteip_module modules/mod_remoteip.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
LoadModule proxy_scgi_module modules/mod_proxy_scgi.so
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule proxy_express_module modules/mod_proxy_express.so
LoadModule slotmem_shm_module modules/mod_slotmem_shm.so
LoadModule ssl_module modules/mod_ssl.so
LoadModule http2_module modules/mod_http2.so
LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so
LoadModule lbmethod_bytraffic_module modules/mod_lbmethod_bytraffic.so
LoadModule lbmethod_bybusyness_module modules/mod_lbmethod_bybusyness.so
LoadModule lbmethod_heartbeat_module modules/mod_lbmethod_heartbeat.so
LoadModule suexec_module modules/mod_suexec.so
LoadModule rewrite_module modules/mod_rewrite.so

在模块结尾部分添加如下内容:

<IfModule http2_module>
ProtocolsHonorOrder On
Protocols h2 http/1.1
</IfModule>

修改以下参数配置

将用户组设置为:

User www
Group www

默认值:

#ServerName www.example.com:80

修改为:

ServerName 0.0.0.0:80

注意:如果基于端口创建虚拟主机,请换行加端口,然后在虚拟主机配置文件中指定端口即可。

将配置文件中的所有:

AllowOverride None

修改为:

AllowOverride All

在以下内容位置:

AddType application/x-compress .Z
AddType application/x-gzip .gz .tgz

添加:

AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps

取消以下注释并添加apache支持python:

AddHandler cgi-script .cgi .py

取消以下注释:

Include conf/extra/httpd-mpm.conf
Include conf/extra/httpd-vhosts.conf
Include conf/extra/httpd-default.conf

以下内容在文件尾部添加

开启GZIP:

<IfModule mod_headers.c>
 AddOutputFilterByType DEFLATE text/html text/plain text/css text/xml text/javascript
 <FilesMatch "\.(js|css|html|htm|png|jpg|swf|pdf|shtml|xml|flv|gif|ico|jpeg)$">
 RequestHeader edit "If-None-Match" "^(.*)-gzip(.*)$" "$1$2"
 Header edit "ETag" "^(.*)-gzip(.*)$" "$1$2"
 </FilesMatch>
 DeflateCompressionLevel 6
 SetOutputFilter DEFLATE
</IfModule>

设置apache安全:

ProtocolsHonorOrder On
PidFile /usr/local/apache/logs/httpd.pid
ServerTokens ProductOnly
ServerSignature Off

引入虚拟主机配置文件:

IncludeOptional conf/vhost/*.conf

7.创建目录及虚拟主机配置文件

$ mkdir -p /usr/local/apache/conf/vhost
$ mkdir -p /data/apps/web/renwolecom
$ vim /usr/local/apache/conf/vhost/renwolecom.conf

插入以下内容:

<VirtualHost *:80>
 ServerAdmin webmaster@example.com
 DocumentRoot "/data/apps/web/renwolecom"
 ServerName www.renwole.com
 ServerAlias renwole.com
 errorDocument 404 /404.html
 ErrorLog "/usr/local/apache/logs/renwolecom-error_log"
 CustomLog "/usr/local/apache/logs/renwolecom-access_log" combined

<FilesMatch \.php$>
 SetHandler "proxy:unix:/tmp/php-cgi.sock|fcgi://localhost"
 </FilesMatch>

<Directory "/data/apps/web/renwolecom">
 SetOutputFilter DEFLATE
 Options FollowSymLinks
 AllowOverride All
 Require all granted
 DirectoryIndex index.php index.html index.htm default.php default.html default.htm
 </Directory>
</VirtualHost>

以上内容请根据自己的网站实际路径修改。

说明:如果没有域名,请将域名绑定部分修改为127.0.0.1,在http.conf中添加其他端口即可实现IP+端口访问,要记得防火墙放行端口。

注意:建议清空httpd-vhosts.conf中的内容,或者不开启引用,否则重启httpd服务时会有警告,但不影响使用,主要原因是找到默认配置中的网站目录路径。

8.创建system系统单元启动文件

$ vim /usr/lib/systemd/system/httpd.service

添加以下内容:

[Unit]
Documentation=man:systemd-sysv-generator(8)
SourcePath=/usr/local/apache/bin/apachectl
Description=LSB: starts Apache Web Server
Before=runlevel2.target
Before=runlevel3.target
Before=runlevel4.target
Before=runlevel5.target
Before=shutdown.target
After=all.target
After=network-online.target
Conflicts=shutdown.target

[Service]
Type=forking
Restart=no
TimeoutSec=5min
IgnoreSIGPIPE=no
KillMode=process
GuessMainPID=no
RemainAfterExit=yes
ExecStart=/usr/local/apache/bin/apachectl start
ExecStop=/usr/local/apache/bin/apachectl stop

9.加入开机自启/启动/停止/重启

$ systemctl enable httpd
$ systemctl start httpd
$ systemctl stop httpd
$ systemctl restart httpd

10.设置Firewalld防火墙

$ firewall-cmd --permanent --zone=public --add-service=http
$ firewall-cmd --permanent --zone=public --add-service=https
$ firewall-cmd --reload

接下来你就可以使用域名或IP访问你的网站了。

11.部署PHP篇

请参阅《Centos 7源码编译安装 php7.1 生产篇

12.部署Mysql篇

请参阅《Centos 7二进制安装配置 MariaDB(MySQL)数据库

Apache HTTP服务器的安装与配置至此已经结束,如果在安装配置过程中出现任何报错,请查看/usr/local/apache/logs/下的错误日志,以便你能快速解决所遇到的问题。

若还有其他指教,欢迎你的留言。

Apache Nginx 禁止目录执行PHP脚本文件

我们在搭建网站的时候,可能需要单独对一些目录进行设置权限,以达到我们需要的安全效果。下面举例说明在Apache或Nginx下如何设置禁止某个目录执行php文件。

1.Apache配置

<Directory /apps/web/renwole/wp-content/uploads>
 php_flag engine off
</Directory>
<Directory ~ "^/apps/web/renwole/wp-content/uploads">
 <Files ~ ".php">
 Order allow,deny
 Deny from all
 </Files>
</Directory>

2.Nginx配置

location /wp-content/uploads {
    location ~ .*\.(php)?$ {
    deny all;
    }
}

Nginx禁止多个目录执行PHP:

location ~* ^/(css|uploads)/.*\.(php)${
    deny all;
}

配置完成后,重载配置文件或重启Apache或Nginx服务,之后所有通过uploads来访问php文件,都将返回403,大大地增加了web目录安全性。

安装配置 Kafka Manager 分布式管理工具

Kafka Manager 特性,它支持以下内容(官方译解):

管理多个群集
容易检查集群状态(主题,消费者,偏移量,经纪人,副本分发,分区分配)
运行首选副本选举
使用选项生成分区分配,以选择要使用的代理
运行分区的重新分配(基于生成的分配)
创建可选主题配置的主题(0.8.1.1具有不同于0.8.2+的配置)
删除主题(仅支持0.8.2+,并记住在代理配​​置中设置delete.topic.enable = true)
主题列表现在表示标记为删除的主题(仅支持0.8.2+)
批量生成多个主题的分区分配,并选择要使用的代理
批量运行多个主题的分区重新分配
将分区添加到现有主题
更新现有主题的配置
可选地,启用JMX轮询代理级和主题级度量。
可选地筛选出在zookeeper中没有ids / owner /&offset /目录的消费者。

要求:

Kafka 0.8.. or 0.9.. or 0.10..
Java 8+

Kafka Server 的安装:

在Centos 7上安装配置 Apche Kafka 分布式消息系统集群

1.安装sbt工具:

# curl //bintray.com/sbt/rpm/rpm > bintray-sbt-rpm.repo
# mv bintray-sbt-rpm.repo /etc/yum.repos.d/
# yum install sbt -y

2.构建kafka-manager包

生成的包会在 kafka-manager/target/universal 下面。kafka-manager只需要Java环境就可以运行,在部署的机器上不需要安装sbt。

# cd /usr/local
# git clone //github.com/yahoo/kafka-manager
# cd kafka-manager
# ./sbt clean dist #时间较久,大约30-60分钟左右

注: kafka manager 1.3.3.22  点此 下载。

移动:

# mv target/universal/kafka-manager-1.3.3.13.zip /usr/local/

解压&创建软连接:

# unzip kafka-manager-1.3.3.13.zip
# ln -s kafka-manager-1.3.3.13 kafka-manager

修改配置:

# vim kafka-manager/conf/application.conf
kafka-manager.zkhosts="10.10.204.63:2181,10.10.204.64:2181,10.10.204.65:2181"

3.启动kafka-manager

执行命令后窗口会出现启动日志,当前会话会静止,需要重开终端。结束当前会话(Ctrl+c,同时会自动退出kafka-manager)。

# kafka-manager/bin/kafka-manager

启动后,你可以使用 IP:9000 访问。

4.为了能使用systemctl便于管理,下面创建系统单元文件(开机自启动):

# vim /usr/lib/systemd/system/kafka-manager.service

[Unit]
 Description=Redis persistent key-value database
 After=network.target

[Service]
 User=kafka
 Group=kafka
 ExecStart=/usr/local/kafka-manager/bin/kafka-manager -Dconfig.file=/usr/local/kafka-manager/conf/application.conf
 ExecStop=/usr/local/kafka-manager/bin/kafka-manager stop
 Restart=always

[Install]
 WantedBy=multi-user.target

重载systemctl配置并加入开机自启动:

# systemctl daemon-reload
# systemctl enable kafka-manager
# systemctl start kafka-manager

加入防火墙:

# firewall-cmd --permanent --add-port=9000/tcp
# firewall-cmd --reload

大功告成。

在Centos 7上安装配置 Apche Kafka 分布式消息系统集群

Apache Kafka是一种颇受欢迎的分布式消息代理系统,旨在有效地处理大量的实时数据。Kafka集群不仅具有高度可扩展性和容错性,而且与其他消息代理(如ActiveMQ和RabbitMQ)相比,还具有更高的吞吐量。虽然它通常用作pub/sub消息传递系统,但许多组织也将其用于日志聚合,因为它为发布的消息提供持久存储。

您可以在一台服务器上部署Kafka,也可以构建一个分布式的Kafka集群来提高性能。本文介绍如何在多节点CentOS 7服务器实例上安装Apache Kafka。

先决条件:

欲安装kafka集群服务器,首先要安装以下组件:

Linux JAVA JDK JRE 环境变量安装与配置
在 Linux 多节点安装配置 Apache Zookeeper 分布式集群

服务器列表:

10.10.204.63
10.10.204.64
10.10.204.65

1.安装

创建用户和组:

 # groupadd kafka
 # useradd -g kafka -s /sbin/nologin kafka

下载Kafka包:

 # cd /usr/local
 # wget //apache.fayea.com/kafka/0.10.2.1/kafka_2.10-0.10.2.1.tgz

解压创建软连接:

 # tar zxvf kafka_2.10-0.10.2.1.tgz
 # ln -s kafka_2.10-0.10.2.1 kafka

设置权限及创建Kafka日志存放目录:

 # chown -R kafka:kafka kafka_2.10-0.10.2.1 kafka
 # mkdir -p /usr/local/kafka/logs

添加系统变量:

编辑:/etc/profile 文件,在最下面添加以下内容:

 export KAFKA_HOME=/usr/local/kafka_2.10-0.10.2.1
 export PATH=$KAFKA_HOME/bin:$PATH

使变量生效:

 # source /etc/profile

2.配置

修改添加Kafka服务器的配置文件:

 # cd /usr/local/kafka/config
 # vim server.properties

#唯一值,每个server填写不一样。
broker.id=63
#允许删除主题。
delete.topic.enable=true
#修改;协议、当前broker机器ip、端口,此值可以配置多个,跟SSL等有关系。
listeners=PLAINTEXT://10.10.204.63:9092
#修改;kafka数据的存放地址,多个地址的话用逗号分割,例如 /data/kafka-logs-1,/data/kafka-logs-2。
log.dirs=/usr/local/kafka/logs/kafka-logs
#每个topic的分区个数,若是在topic创建时候没有指定的话会被topic创建时的指定参数覆盖。
num.partitions=3
#新增;表示消息体的最大大小,单位是字节。
message.max.bytes=5242880
#新增;是否允许自动创建topic,若是false,就需要通过命令创建topic。
default.replication.factor=2
#新增;replicas每次获取数据的最大大小。
replica.fetch.max.bytes=5242880
#新增;配置文件中必须使用以下配置,否则只会标记为删除,而不是真正删除。
delete.topic.enable=true
#新增;是否允许 leader 进行自动平衡,boolean 值,默认为 true。
auto.leader.rebalance.enable=true
#kafka连接的zk地址,各个broker配置一致。
zookeeper.connect=10.10.204.63:2181,10.10.204.64:2181,10.10.204.65:2181

#可选配置
#是否允许自动创建 topic,boolean 值,默认为 true。
auto.create.topics.enable=true
#指定 topic 的压缩方式,string 值,可选有。
compression.type=high
#会把所有的日志同步到磁盘上,避免重启之后的日志恢复,减少重启时间。
controlled.shutdown.enable=true

注:broker的配置文件中有zookeeper的地址,也有自己的broker ID, 当broker启动后,会在zookeeper中新建一个znode。

修改其他配置文件:

 # vim zookeeper.properties

修改为:

 dataDir=/usr/local/zookeeper/data
新增:

 server.1=10.10.204.63:2888:3888
 server.2=10.10.204.64:2888:3888
 server.3=10.10.204.65:2888:3888

修改以下配置文件:

# vim producer.properties

bootstrap.servers=10.10.204.63:9092,10.10.204.64:9092,10.10.204.65:9092

# vim consumer.properties

zookeeper.connect=10.10.204.63:2181,10.10.204.64:2181,10.10.204.65:2181

3.启动

启动所有节点kafka服务(可以通过查看日志,或者检查进程状态,保证Kafka集群启动成功):

# /usr/local/kafka/bin/kafka-server-start.sh /usr/local/kafka/config/server.properties

执行上述命令后,会出来滚动的启动信息,直至窗口静止,此时需重开终端检查是否启动成功;

# jps
 9939 Jps
 2201 QuorumPeerMain
 2303 Kafka

4.使用测试

下面操作可以在任意节点,重新打开一个终端操作:

执行以下命令,建立一个名为 renwole 的topic。

 # cd /usr/local/kafka/bin
 # ./kafka-topics.sh --create --zookeeper 10.10.204.63:2181,10.10.204.64:2181,10.10.204.65:2181 --replication-factor 1 --partitions 1 --topic renwole
 Created topic "renwole".

解释:

 --replication-factor 1 复制1份
 --partitions 1 创建1个分区
 --topic 主题为renwole

查看已创建的topic:

# ./kafka-topics.sh --list --zookeeper 10.10.204.63:2181
 _consumer_offsets
 renwole

注:可以配置 broker 自动创建 topic。

发送消息(Kafka 使用一个简单的命令行producer(然后可以随意输入内容,回车可以发送,ctrl+c 退出)默认的每条命令将发送一条消息。):

# ./kafka-console-producer.sh --broker-list 10.10.204.64:9092 --topic renwole

在消息接收端,执行以下命令查看收到的消息:

# ./kafka-console-consumer.sh --bootstrap-server 10.10.204.63:9092 --topic renwole --from-beginning

执行以下命令删除topic:

# ./kafka-topics.sh --delete --zookeeper 10.10.204.63:2181,10.10.204.64:2181,10.10.204.65:2181 --topic renwole

5.查看集群状态

kafka已经成功完成安装,查看kafka集群节点ID状态:

注:可在任意节点连接zookeeper客户端。

 # cd /usr/local/zookeeper/bin
 # ./zkCli.sh
 Connecting to localhost:2181
 [myid:] - INFO [main:Environment@100] - Client environment:zookeeper.version=3.4.10-39d3a4f269333c922ed3db283be479f9deacaa0f, built on 03/23/2017 10:13 GMT
 [myid:] - INFO [main:Environment@100] - Client environment:host.name=10-10-204-63.10.10.204.63
 [myid:] - INFO [main:Environment@100] - Client environment:java.version=1.8.0_144
 [myid:] - INFO [main:Environment@100] - Client environment:java.vendor=Oracle Corporation
 [myid:] - INFO [main:Environment@100] - Client environment:java.home=/usr/java/jdk1.8.0_144/jre
 [myid:] - INFO [main:Environment@100] - Client environment:java.class.path=/usr/local/zookeeper/bin/../build/classes:/usr/local/zookeeper/bin/../build/lib/*.jar:/usr/local/zookeeper/bin/../lib/slf4j-log4j12-1.6.1.jar:/usr/local/zookeeper/bin/../lib/slf4j-api-1.6.1.jar:/usr/local/zookeeper/bin/../lib/netty-3.10.5.Final.jar:/usr/local/zookeeper/bin/../lib/log4j-1.2.16.jar:/usr/local/zookeeper/bin/../lib/jline-0.9.94.jar:/usr/local/zookeeper/bin/../zookeeper-3.4.10.jar:/usr/local/zookeeper/bin/../src/java/lib/*.jar:/usr/local/zookeeper/bin/../conf:.:/usr/java/jdk1.8.0_144/jre/lib/rt.jar:/usr/java/jdk1.8.0_144/lib/dt.jar:/usr/java/jdk1.8.0_144/lib/tools.jar:/usr/java/jdk1.8.0_144/jre/lib
 [myid:] - INFO [main:Environment@100] - Client environment:java.library.path=/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
 [myid:] - INFO [main:Environment@100] - Client environment:java.io.tmpdir=/tmp
 [myid:] - INFO [main:Environment@100] - Client environment:java.compiler=
 [myid:] - INFO [main:Environment@100] - Client environment:os.name=Linux
 [myid:] - INFO [main:Environment@100] - Client environment:os.arch=amd64
 [myid:] - INFO [main:Environment@100] - Client environment:os.version=3.10.0-514.21.2.el7.x86_64
 [myid:] - INFO [main:Environment@100] - Client environment:user.name=root
 [myid:] - INFO [main:Environment@100] - Client environment:user.home=/root
 [myid:] - INFO [main:Environment@100] - Client environment:user.dir=/usr/local/zookeeper-3.4.10/bin
 [myid:] - INFO [main:ZooKeeper@438] - Initiating client connection, connectString=localhost:2181 sessionTimeout=30000 watcher=org.apache.zookeeper.ZooKeeperMain$MyWatcher@69d0a921
 Welcome to ZooKeeper!
 [myid:] - INFO [main-SendThread(localhost:2181):ClientCnxn$SendThread@1032] - Opening socket connection to server localhost/0:0:0:0:0:0:0:1:2181. Will not attempt to authenticate using SASL (unknown error)
 JLine support is enabled
 [myid:] - INFO [main-SendThread(localhost:2181):ClientCnxn$SendThread@876] - Socket connection established to localhost/0:0:0:0:0:0:0:1:2181, initiating session
 [myid:] - INFO [main-SendThread(localhost:2181):ClientCnxn$SendThread@1299] - Session establishment complete on server localhost/0:0:0:0:0:0:0:1:2181, sessionid = 0x35ddf80430b0008, negotiated timeout = 30000
 WATCHER::
 WatchedEvent state:SyncConnected type:None path:null
 [zk: localhost:2181(CONNECTED) 0] ls /brokers/ids #查看ID
 [63, 64, 65]

可以看到三台kafka实例ID都在线,如果模拟任意一台节点掉线,查看结果就会不同(这个ID号是前面设置的 broker.id )。

开放端口加入防火墙:

# firewall-cmd --permanent --add-port=9092/tcp
# firewall-cmd --reload

6.开机启动

创建system单元文件:

在 /usr/lib/systemd/system 目录下创建 kafka.service 填写以下内容:

[Unit]
 Description=Apache Kafka server (broker)
 Documentation=//kafka.apache.org/documentation/
 Requires=network.target remote-fs.target
 After=network.target remote-fs.target

[Service]
 Type=simple
 Environment="LOG_DIR=/usr/local/kafka/logs"
 User=kafka
 Group=kafka
 #Environment=JAVA_HOME=/usr/java/jdk1.8.0_144
 ExecStart=/usr/local/kafka/bin/kafka-server-start.sh /usr/local/kafka/config/server.properties
 ExecStop=/usr/local/kafka/bin/kafka-server-stop.sh
 Restart=on-failure
 SyslogIdentifier=kafka

[Install]
 WantedBy=multi-user.target

启动kafka实例服务器:

# systemctl daemon-reload
# systemctl enable kafka.service
# systemctl start kafka.service
# systemctl status kafka.service

7.此外Kafka也可以通过 Web UI 界面进行集群的管理,你可以参阅:

安装配置 Kafka Manager 分布式管理工具

滴滴,好了,到目前为止,kafka分布式消息队列已经部署完成,其中包括必要的优化信息。目前,您可以用于大多数编程语言的Kafka客户端去创建Kafka生产者和消费者,轻松地将其用于您的项目中。

参考资料:
//kafka.apache.org/documentation.html#quickstart
//www.ibm.com/developerworks/cn/opensource/os-cn-kafka/
//tech.meituan.com/kafka-fs-design-theory.html
//blog.jobbole.com/99195/

Redisson 缓存 Tomcat Redis Session Manager 变量

部署负载均衡时,使用一台Nginx作为前端服务器,多台Tomcat作为后端服务器。Nginx 会根据负载策略把请求分发给Tomcat服务器。默认Tomcat服务器的session(共享会话)是不可跨越服务器的,若是同一个用户的不同请求被分发到不同的Tomcat服务器,就会造成 session 变量丢失,需要用户重新登录。在讲解Redisson之前,我先来分析以下两种方案的Session会话共享。

方案一:Nginx原生 Upstream ip_hash

ip_hash 是根据请求的IP进行分发,对于同一个IP的请求会转发到同一台Tomcat服务器。

1.Nginx 配置如下:《Nginx 1.3 集群负载均衡器 反向代理安装配置优化

 upstream webservertomcat {
 ip_hash;
 server 10.10.204.63:8023 weight=1 max_fails=2 fail_timeout=2;
 server 10.10.204.64:8023 weight=1 max_fails=2 fail_timeout=2;
 #server 127.0.0.1:8080 backup;
 }
 server {
 listen 80;
 server_name www.myname.com myname.com;
 location / {
 proxy_pass //webservertomcat;
 proxy_redirect off;
 proxy_set_header Host $host;
 proxy_set_header X-Real-IP $remote_addr;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 client_max_body_size 10m;
 client_body_buffer_size 128k;
 proxy_connect_timeout 90;
 proxy_send_timeout 90;
 proxy_read_timeout 90;
 proxy_buffer_size 4k;
 proxy_buffers 4 32k;
 proxy_busy_buffers_size 64k;
 proxy_temp_file_write_size 64k;
 add_header Access-Control-Allow-Origin *;
 }
 }

以上配置生产环境不建议使用,原因有二:

1.Nginx可能不是最前端的服务器,如Squid或CDN作为前端缓存,则Nginx实际是拿Squid或CDN服务器的IP地址,达不到根据客户端请求IP分流的效果。
2.有些机构是使用动态虚拟IP或有多个出口IP,用户访问会切换IP,则无法将某个用户的请求固定到同一个Tomcat服务器。

方案二:Nginx_Upstream_jvm_route

Nginx_upstream_jvm_route 是一个第三方 nginx 扩展模块,该模块通过 session cookie 实现 session 会话粘性,如果在cookie和url中并没有session,则这只是个简单的round-robin 负载均衡。

实现方法:用户初次请求分发到后端Server时;会把响应的Server标识添加到名称为JSESSIONID的cookie中,再次请求时;jvm_route看到session中有后端服务器的名称,它就把请求转到对应的服务器上。模块地址://code.google.com/archive/p/nginx-upstream-jvm-route/

1.Nginx配置如下:

 upstream tomcats_jvm_route {
 server 10.10.204.63:8023 srun_id=tomcat1;
 server 10.10.204.64:8023 srun_id=tomcat2;
 jvm_route $cookie_JSESSIONID|sessionid reverse;
 }

2.在多个Tomcat的server.xml添加配置如下:

 <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">
 <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat2">

3.配置后,请求的名称为JSESSIONID的cookie末尾会被添加服务器标识,如下:

 JSESSIONID=33775B80D8E0DB5AEAD61F86D6666C45.tomcat2;

4.生产环境不建议使用,原因:

4.1根据tomcat的特性,当server.xml配置文件中加了jvmRoute值后,会给sessionid加上jvmRoute值的后缀,根据这一特性 nginx_upstream_jvm_route对每次访问请求中的sessionId的值自动匹配对应的server。这样就会每次都访问都会到同一个Tomcat Server,这样就解决了访问不同tomcat节点session发生变化的问题。但是这种方式会出现一个问题,当一直被访问的Tomcat服务器宕机后,负载就会将用户分配到其他Server,这样就会造成session发生变化,从而就需要重新登录。

方案三:Tomcat Redis Session Manager

使用 Redis 共享 session,也就是本节中重点讲解的部分。以上两种方案均是将Session存储在Tomcat容器中,当请求从一个Tomcat转发到另一个Tomcat时,Session就会失效,因为Session在各个Tomcat中不能共享。如果使用Redis等缓存数据库系统存储Session,就可以在Tomcat实例之间实现Session共享。

Java框架redisson实现Tomcat会话管理器(Tomcat Session Manager),支持Apache Tomcat 6.x,7.x和8.x。配置方法如下:

1.编辑 TOMCAT_BASE/conf/context.xml 文件节点,添加以下内容:

<Manager className="org.redisson.tomcat.RedissonSessionManager"<Manager className="org.redisson.tomcat.RedissonSessionManager"  configPath="${catalina.base}/redisson-config.json" />

注:configPath – 是指的Redisson的JSON或YAML格式的配置文件路径。配置文件详见这里

2.拷贝相应的***两个***JAR包到指定的TOMCAT_BASE/lib目录下:

适用于 JDK 1.8+

redisson-all-3.5.0.jar

for Tomcat 6.x

redisson-tomcat-6-3.5.0.jar

for Tomcat 7.x

redisson-tomcat-7-3.5.0.jar

for Tomcat 8.x

redisson-tomcat-8-3.5.0.jar

3.按照 [Single instance mode]单实例模式的说明,创建编辑 Json 格式的 redisson-config.json 文件,添加以下内容,并将其上传到TOMCAT_BASE下,重载Tomcat服务即可。

{
 "singleServerConfig":{
 "idleConnectionTimeout":10000,
 "pingTimeout":1000,
 "connectTimeout":10000,
 "timeout":3000,
 "retryAttempts":3,
 "retryInterval":1500,
 "reconnectionTimeout":3000,
 "failedAttempts":3,
 "password":null,
 "subscriptionsPerConnection":5,
 "clientName":null,
 "address": "redis://127.0.0.1:6379",
 "subscriptionConnectionMinimumIdleSize":1,
 "subscriptionConnectionPoolSize":50,
 "connectionMinimumIdleSize":10,
 "connectionPoolSize":64,
 "database":0,
 "dnsMonitoring":false,
 "dnsMonitoringInterval":5000
 },
 "threads":0,
 "nettyThreads":0,
 "codec":null,
 "useLinuxNativeEpoll":false
 }

4.开始测试session。创建session.jsp并添加以下代码,上传到TOMCAT_BASE/webapps/ROOT/下。

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>shared session</title>
</head>
<body>
<br>session id=<%=session.getId()%>
</body>
</html>

5.浏览器访问会出现以下会话信息

 session id=1D349A69E8F5A27E1C12DEEFC304F0DC

6.现在查看Redis中是否存储了该值,如果存在会话值,此时你重启Tomcat后,该会话值也不会发生变化。

 # redis-cli
 127.0.0.1:6379> keys *
 1) "redisson_tomcat_session:1D349A69E8F5A27E1C12DEEFC304F0DC"

已经存储成功。

如果是Redis集群或多实例模式,可参阅以下更多资料进行配置:

//github.com/redisson/redisson/wiki/14.-Integration%20with%20frameworks#144-tomcat-redis-session-manager
//github.com/redisson/redisson/wiki/2.-Configuration
//github.com/redisson/redisson/wiki/2.-%E9%85%8D%E7%BD%AE%E6%96%B9%E6%B3%95 (中文文档)