November 2018
M T W T F S S
« Oct    
 1234
567891011
12131415161718
19202122232425
2627282930  

Categories

WordPress Quotes

A real decision is measured by the fact that you've taken a new action. If there's no action, you haven't truly decided.
Tony Robbins

Recent Comments

November 2018
M T W T F S S
« Oct    
 1234
567891011
12131415161718
19202122232425
2627282930  

Short Cuts

2012 SERVER (64)
2016 windows (9)
AIX (13)
Amazon (34)
Ansibile (18)
Apache (133)
Asterisk (2)
cassandra (2)
Centos (209)
Centos RHEL 7 (258)
chef (3)
cloud (2)
cluster (3)
Coherence (1)
DB2 (5)
DISK (25)
DNS (9)
Docker (28)
Eassy (11)
ELKS (1)
EXCHANGE (3)
Fedora (6)
ftp (5)
GIT (3)
GOD (2)
Grub (1)
Hacking (10)
Hadoop (6)
horoscope (23)
Hyper-V (10)
IIS (15)
IPTABLES (15)
JAVA (7)
JBOSS (32)
jenkins (1)
Kubernetes (2)
Ldap (5)
Linux (189)
Linux Commands (167)
Load balancer (5)
mariadb (14)
Mongodb (4)
MQ Server (22)
MYSQL (84)
Nagios (5)
NaturalOil (13)
Nginx (30)
Ngix (1)
openldap (1)
Openstack (6)
Oracle (34)
Perl (3)
Postfix (19)
Postgresql (1)
PowerShell (2)
Python (3)
qmail (36)
Redis (12)
RHCE (28)
SCALEIO (1)
Security on Centos (29)
SFTP (1)
Shell (64)
Solaris (58)
Sql Server 2012 (4)
squid (3)
SSH (10)
SSL (14)
Storage (1)
swap (3)
TIPS on Linux (28)
tomcat (60)
Uncategorized (29)
Veritas (2)
vfabric (1)
VMware (28)
Weblogic (38)
Websphere (71)
Windows (19)
Windows Software (2)
wordpress (1)
ZIMBRA (17)

WP Cumulus Flash tag cloud by Roy Tanck requires Flash Player 9 or better.

Who's Online

16 visitors online now
4 guests, 12 bots, 0 members

Hit Counter provided by dental implants orange county

tomcat tuning

Sync sync disk

echo 3 > /proc/sys/vm/drop_caches # Clean up useless memory space

Tomcat8 final configuration
1.${tomcat}/bin/catalina.sh Join
1.${tomcat}/bin/catalina.sh
JAVA_OPTS=”-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms1G -Xmx1G -Xss256k -XX:NewSize=1G -XX:MaxNewSize=1G
-XX:PermSize=128m -XX:MaxPermSize=128m -XX:+DisableExplicitGC”

2.
2.
JAVA_OPTS=”$JAVA_OPTS -server -Xms3G -Xmx3G -Xss256k -XX:PermSize=128m -XX:MaxPermSize=128m -XX:+UseParallelOldGC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/usr/aaa/dump -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:/usr/tomcat/dump/heap_trace.txt -XX:NewSize=1G -XX:MaxNewSize=1G”

2.${tomcat}/conf/server.xml
Open commented out

<Executor name=”tomcatThreadPool” namePrefix=”catalina-exec-”
maxThreads=”300″ minSpareThreads=”50″/>

Add options not found in Connector

<Connector port=”80″ protocol=”org.apache.coyote.http11.Http11NioProtocol”
executor=”tomcatThreadPool”
minSpareThreads=”50″
maxSpareThreads=”500″
enableLookups=”false”
acceptCount=”500″
debug=”0″
connectionTimeout=”10000″
redirectPort=”8443″
compression=”on”
compressableMimeType=”text/html,text/xml,text/plain,text/javascript,text/css”
disableUploadTimeout=”true”
URIEncoding=”UTF-8″
useBodyEncodingForURI=”true”
/>

Detailed explanation of each parameter:

-Xms: Set the JVM initial memory size (default is 1/64 of physical memory)

-Xmx: Set the maximum memory that the JVM can use (default is 1/4 of physical memory, recommended: 80% of physical memory)

-Xmn: Set the minimum memory of the JVM (128-256m is enough, generally not set)

The default free heap memory is less than
At 40%, the JVM will increase the heap until the maximum limit of -Xmx; when the free heap memory is greater than 70%, the JVM will reduce the heap to the minimum limit of -Xms. So the server is generally set to -Xms,
-Xmx is equal to avoid resizing the heap after each GC.

In larger applications, the default memory is not enough and may cause the system to fail. A common problem is to report a Tomcat memory overflow error “java.lang.OutOfMemoryError:
Java heap space”, causing the client to display 500 errors.

-XX:PermSize : Perm memory size when starting the JVM

-XX:MaxPermSize : is the maximum available Perm memory size (default is 32M)

-XX:MaxNewSize, default is 16M

The full name of PermGen space is Permanent Generation
Space, refers to the permanent storage area of ??memory, this memory is mainly stored by the JVM Class and Meta information, Class will be placed in PermGen when it is Loader
In space, it is different from the Heap area that stores the instance (Instance), GC (Garbage
Collection) will not be in the main program runtime against PermGen
Space is cleaned up, so if your application has a very CLASS, it is likely to appear “java.lang.OutOfMemoryError:
PermGen space” error.

For WEB projects, when jvm loads a class, the objects in the permanent domain increase sharply, so that jvm constantly adjusts the size of the permanent domain. To avoid adjustments, you can use more parameter configuration. If your WEB
APP uses a large number of third-party jars, the size of which exceeds the default size of jvm, then this error message will be generated.

Other parameters:

-XX:NewSize: The default is 2M. This value is set to a large adjustable new object area, reducing Full.
GC times

-XX:NewRatio : Change the proportion of new and old space, which means that the size of the new space is 1/8 of the old space (default is 8)

-XX:SurvivorRatio: Change the size ratio of the Eden object space and the remaining space, meaning that the Eden object is empty.

The size between the two is greater than the survivor space by 2 times survivorRatio (default is 10)

-XX:userParNewGC can be used to set parallel collection [multiple CPU]

-XX:ParallelGCThreads can be used to increase parallelism [multiple CPU]

-XXUseParallelGC can be set to use parallel clear collector [multi-CPU]

maxThreads
The maximum number of request processing threads to be created by this Connector, which therefore determines the maximum number of simultaneous requests that can be handled.If not specified, this attribute is set to 200. If an executor is associated with this connector, this attribute is ignored as the connector will execute tasks using the executor rather than an internal thread pool.
300
minSpareThreads
The minimum number of threads always kept running. If not specified, the default of 10 is used.
50
connectionTimeout
The number of milliseconds this Connector will wait, after accepting a connection, for the request URI line to be presented. Use a value of -1 to indicate no (i.e. infinite) timeout. The default value is 60000 (i.e. 60 seconds) but note that the standard server.xml that ships with Tomcat sets this to 20000 (i.e. 20 seconds). Unless disableUploadTimeout is set to false, this timeout will also be used when reading the request body (if any).
tcpNoDelay
If set to true, the TCP_NO_DELAY option will be set on the server socket, which improves performance under most circumstances. This is set to true by default.
socketBuffer
The size (in bytes) of the buffer to be provided for socket output buffering. -1 can be specified to disable the use of a buffer. By default, a buffers of 9000 bytes will be used.
server
Overrides the Server header for the http response. If set, the value for this attribute overrides the Tomcat default and any Server header set by a web application. If not set, any value specified by the application is used. If the application does not specify a value then Apache-Coyote/1.1 is used. Unless you are paranoid, you won’t need this feature.
maxHttpHeaderSize
The maximum size of the request and response HTTP header, specified in bytes. If not specified, this attribute is set to 8192 (8 KB).
maxKeepAliveRequests
The maximum number of HTTP requests which can be pipelined until the connection is closed by the server. Setting this attribute to 1 will disable HTTP/1.0 keep-alive, as well as HTTP/1.1 keep-alive and pipelining. Setting this to -1 will allow an unlimited amount of pipelined or keep-alive HTTP requests. If not specified, this attribute is set to 100.
maxConnections
For BIO the default is the value of maxThreads unless an Executor is used in which case the default will be the value of maxThreads from the executor. For NIO the default is 10000. For APR/native, the default is 8192.
keepAliveTimeout
The number of milliseconds this Connector will wait for another HTTP request before closing the connection. The default value is to use the value that has been set for the connectionTimeout attribute. Use a value of -1 to indicate no (i.e. infinite) timeout.

Database Pool Configuration

<Resource name=”jdbc/productdb” auth=”Container” type=”javax.sql.DataSource”
maxTotal=”10″ maxIdle=”30″ maxWaitMillis=”10000″ logAbandoned=”true”
username=”root” password=”admin” driverClassName=”com.mysql.jdbc.Driver”
url=”jdbc:mysql://localhost:3306/products”/>
</Context>

JVM Settings
We have set the minimum and maximum heap size to 1GB respectively as below:

export CATALINA_OPTS=”-Xms1024m -Xmx1024m”

-Xms – Specifies the initial heap memory
-Xmx – Specifies the maximum heap memory

AJP Connector configuration
The AJP connector configuration below is configured so that there are two threads allocated to accept new connections.
This should be configured to the number of processors on the machine however two should be suffice here.
We have also allocated 400 threads to process requests, the default value is 200.
The “acceptCount” is set to 100 which denotes the maximum queue length to be used for incoming connections.
The default value is 10. Lastly we have set the minimum threads to 20 so that there are always 20 threads running in the pool to service requests:

<Connector port=”8009″ protocol=”AJP/1.3″ redirectPort=”8443″ acceptorThreadCount=”2″ maxThreads=”400″ acceptCount=”200″ minSpareThreads=”20″/>

Database Pool Configuration
We have modified the maximum number of pooled connections to 200 so that there are ample connections in the pool to service requests.

<Context>
<Resource name=”jdbc/productdb” auth=”Container” type=”javax.sql.DataSource”
maxTotal=”200″ maxIdle=”30″ maxWaitMillis=”10000″ logAbandoned=”true”
username=”xxxx” password=”xxxx” driverClassName=”com.mysql.jdbc.Driver”
url=”jdbc:mysql://localhost:3306/products”/>
</Context>

JVM Settings
Since we have increased the maximum number of pooled connections and AJP connector thread thresholds above,
we should increase the heap size appropriately. We have set the minimum and maximum heap size to 2GB respectively as below:

export CATALINA_OPTS=”-Xms2048m -Xmx2048m”

JVM Heap Monitoring and Tuning

Specifying appropriate JVM heap parameters to service your deployed applications on Tomcat is paramount to application performance.
There are a number of different ways which we can monitor JVM heap usage including using JDK hotspot tools such as jstat, JConsole etc. –
however to gather detailed data on when and how garbage collection is being performed, it is useful to turn on GC logging on the Tomcat instance.
We can turn on GC logging by modifying the catalina start up script with the following command:

JAVA_OPTS=”$JAVA_OPTS -verbose:gc -Xloggc:gc.log -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps”

We can set the minimum and maximum heap size,
the size of the young generation and the maximum amount of memory to be allocated to the permanent generation used to store application class metadata by specifying the setting the CATALINA_OPTS parameter by executing this command:

export CATALINA_OPTS=”-Xms1024m -Xmx2048m -XX:MaxNewSize=512m -XX:MaxPermSize=256m”

This configuration is optimized for REST/HTTP API call. And it doesn’t use any reverse proxy like Apache, NginX etc. We will reside simple L4 switch infront of tomcat groups.

In addition we will not use Tomcat Clustering, Session etc. So the clustering configuration is omitted.

Listener Setting
<Listener className=”org.apache.catalina.security.SecurityListener” checkedOsUsers=”root” />

checkedOsUser setting means Unix system user “root” cannot start Tomcat. If user starts tomcat as a root user it makes log file as a root user permission. In that case tomcat user cannot delete the log file.

<Listener className=”org.apache.catalina.core.JreMemoryLeakPreventionListener” />

This makes detect memory leak.

Connector Setting
protocol=”org.apache.coyote.http11.Http11Protocol”

It makes tomcat use BIO. Tomcat has options for IO (BIO,NIO,APR). APR is fastest IO setting. It uses Apache web server IO module, so it is fastest. But it uses C code (JNI call), it can have a risk to kill tomcat instance. (with core dump). APR is more faster about 10% than BIO. But BIO is more stable. Use BIO. (Default is BIO)

acceptCount=”10?

It specifies server request queue length. If message is queued in the request queue, it means server cannot handle incoming message (it is overloaded). It will wait for idle thead and the request message will be pending. This setting reduce total size of request queue to 10. If the queue has been overflowed, client will get a error. It can protect server from high overload and let system manager to know the server has been overloaded.

enableLookups=”false”

In Java Servlet Code, user can look up request message origin (IP or URL).

For example user in yahoo.com send request to server, and Tomcat try to resolve incoming request IP address.
“enableLooksups” option enables return DNS name not a IP address. During this processing Tomcat look up DNS.
It brings performance degradation. This option removes DNS look up stage and increase performance.

compression=”off”

We are using REST protocol not a normal web contents like HTML,Image etc.
This options allows to compress HTTP message. It consumes computing power but it can reduce network payload.
In our environment compression is not required. It is better to save computing power. And in some particular Telco network, compression is not supported.

connectionTimeout=”10000?

It is HTTP Connection time out (client to server). It is milliseconds. (10,000 = 10 sec).

If server cannot make a connection from client til 10 sec. It will throw HTTP time out error.
In normal situation, our API response time is under 5 sec. So 10 sec means, server has been overloaded.
The reason why I increased the time up to 10 sec is, depends on network condition, connection time will be deferred.

maxConnections=”8192?

The maximum number of connection, tomcat can handle. It means tomcat can handle maximum 8192 socket connection in a time. This value is restricted by Unix system parameter “ulimit –f” (You can check up in unix console)

maxKeepAliveRequests=”1?

As I mentioned above, this configuration is optimized to REST API request not a common web system. It means client will send REST API call only. It sends the request and get a response. Client will not send request in a short time. It means we cannot reuse the connection from the client. So this setting turn of HTTP Keep Alive. (After response the request from client, tomcat disconnect the connection immediately)

maxThreads=”100?

This defines total number of thread in Tomcat. It represents max number of active user at that time. Usually 50~500 is good for performance. And 100~200 is best (it is different depends on use case scenario).

Please test with 100 and 200 values and find value for performance. This parameter also get a impact from DB connection pool setting, even if we have a lot of thread , and the total number of db connection is not enough, the thread will wait to acquire the connection.

tcpNoDelay=”true”

This allows us to use TCP_NO_DELAY in tcp/ip layer. It makes send small packet without delay. In TCP, to reduce small package congestion, it gathers small packet to tcp buffer until it has been filled and send the packet. TCP_NO_DELAY option makes send small packet immediately even though TCP buffer is not full.

JVM Tuning
Java Virtual Machine tuning is also very important factor to run Tomcat

The focus of JVM tuning is reducing Full GC time.

-server

This option makes JVM to optimize server application. It tunes HotSpot compiler etc internally. This option is very important and mandatory in server side application

-Xmx1024m –Xms1024m -XX:MaxNewSize=384m -XX:MaxPermSize=128m

This memory tuning options, our infrastructure is using c1.mediuem amazon instance, so the available memory is about 1.7 gb total. Heap size is 1G and let them to have fixed size. It defines max 1Gb, min 1Gb heap size. The NewSize is 384mb (1/3 size of total heap size). 1/3 New Size is best performance usually. Perm size is defines area of memory to load class. 64mb is enough. But we will use 128m first time and tune based on gc log analysis later.

Total physical memory consumption is 1G heap + 128mb perm = 1.128 GB and JVM internally uses memory to run JVM itself. It consumes about 350~500mb. So total estimated required memory is about 1.128GB+500m = 1.5 GB.

As I mentioned, c1.mediuem size has only 1.7GB physical memory. If consumed memory exceeds actual physical memory, it makes disk swapping. If JVM memory is swapped out to disk, the performance is significantly degraded. Please take care swapping is not occurred.

-XX:-HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./java_pid<pid>.hprof

These options are for trouble shooting “OOM (Java Out Of Memory Error”. If out of memory error has been occurred. The memory layout will be dumped to disk. The location of dumpfile is specified by “-XX:HeapDumpPath” option

-XX:ParallelGCThreads=2 -XX:-UseConcMarkSweepGC

These options specify GC strategy. It uses ParallelGC for Minor collection and 2 threads will be used for the Minor GC. And for Old area, concurrent gc will be used. It will reduce Full gc time

-XX:-PrintGC -XX:-PrintGCDetails -XX:-PrintGCTimeStamps -XX:-TraceClassUnloading -XX:-TraceClassLoading

These option specifies GC logging. It logs the GC log detail to stderr (console output). It shows usage trend os Java Heap memory, time stamp etc. (it contains old,new & perm area usage).

Especially, ClassLoading & UnLoading option show what class is loaded and unloaded to memory. It helps us to trace Perm Out of memory error.

CentOS 7.3 compile and install Nginx 1.12.2

CentOS 7.3 compile and install Nginx 1.12.2

1. Introduction to
Nginx Nginx (pronounced [engine x]) was developed for performance optimization. Its best known advantages are its stability and low system resource consumption, as well as high processing power for concurrent connections (single physical server available) Supporting 30,000 to 50,000 concurrent connections), is a high-performance HTTP and reverse proxy server, and an IMAP/POP3/SMTP proxy service.

Linux system: CentOS 7.3

2. Installation preparation
2.1 gcc installation

To install nginx, you need to compile the source code downloaded from the official website first, and compile it depends on the gcc environment. If there is no gcc environment, you need to install it:

[root@nginx ~]# yum -y install gcc-c++

2.2 pcre installation

PCRE (Perl Compatible Regular Expressions) is a Perl library that includes a perl-compatible regular expression library. Nginx’s http module uses pcre to parse regular expressions, so you need to install the pcre library on linux, a secondary development library developed with pcre. Nginx also needs this library.

[root@nginx ~]# yum -y install pcre pcre-devel

2.3 zlib installation

The zlib library provides a variety of ways to compress and decompress. nginx uses zlib to gzip the contents of the http package, so you need to install the zlib library on Centos.

[root@nginx ~]# yum -y install zlib zlib-devel

2.4 OpenSSL installation

OpenSSL is a powerful Secure Sockets Layer cryptography library that includes major cryptographic algorithms, common key and certificate encapsulation management functions, and SSL protocols, and provides a rich set of applications for testing or other purposes.
Nginx supports not only the http protocol, but also https (that is, http on the ssl protocol), so you need to install the OpenSSL library in Centos.

[root@nginx ~]# yum -y install openssl openssl-devel

3. Nginx installation

3.1 Nginx version

Download URL: https://nginx.org/en/download.html

Select the latest stable version of nginx-1.12.2
release notes:

Mainline version: Mainline is the version that Nginx is currently working on. It can be said that the development version of
Stable version: the latest stable version, the recommended version of the production environment
Legacy versions: the legacy version of the legacy version

3.2 Nginx Download

Use the wget command to download

[root@nginx ~]# wget -c https://nginx.org/download/nginx-1.12.2.tar.gz

Install without the wget command:

[root@nginx ~]# yum -y install wget

3.3 Decompression

[root@nginx ~]# tar -zxvf nginx-1.12.2.tar.gz

3.4 Installation and Configuration

3.4.1 Creating a New nginx User and Group

[root@nginx include]# groupadd nginx
[root@nginx include]# useradd -g nginx -d /home/nginx nginx
[root@nginx include]# passwd nginx

3.4.2 Third-party module installation

This article uses the third-party module sticky as an example, the version is 1., 2.5, download address:

You can download it from the Linux Community Resource Station:

——————————————Dividing line—— ————————————

The free download address is at http://linux.linuxidc.com/

Username and password are both www.linuxidc.com

The specific download directory is compiled and installed in the /2000 data/September/27/CentOS 7.3 installation Nginx 1.12.2/

The download method can be found at http://www.linuxidc.com/Linux/2013-07/87684.htm

——————————————Dividing line—— ————————————

Upload and unzip:

[root@nginx ~]# tar -zxvf nginx-goodies-nginx-sticky-module-ng-08a395c66e42..gz
[root@nginx ~]# mv nginx-goodies-nginx-sticky-module-ng-08a395c66e42 nginx-sticky -1.2.5

3.4.3 Installation

[root@nginx ~]# cd nginx-1.12.2
[root@nginx nginx-1.12.2]# ./configure –add-module=/root/nginx-sticky-1.2.5

Specify user, path, and module configuration (optional):

./configure \
–user=nginx –group=nginx \ #Installed user group
–prefix=/usr/local/nginx \
#Specify the installation path –with-http_stub_status_module \ #Monitor nginx state, need to be in nginx.
Conp configuration –with-http_ssl_module \ #Support HTTPS
–with-http_sub_module \ #Support URL redirection
–with-http_gzip_static_module #static compression–
add-module=/root/nginx-sticky-1.2.5 #Install sticky module

3.5 compilation

[root@nginx nginx-1.12.2]# make && make install

Error:

/root/nginx-sticky-1.2.5//ngx_http_sticky_misc.c: In the function ‘ngx_http_sticky_misc_sha1’:
/root/nginx-sticky-1.2.5//ngx_http_sticky_misc.c:176:15: Error: ‘SHA_DIGEST_LENGTH’ is not declared (first used in this function)
u_char hash[SHA_DIGEST_LENGTH];
^
/root/nginx-sticky-1.2.5//ngx_http_sticky_misc.c:176:15: Note: Every undeclared identifier appears in it Only one time is reported in the function
/root/nginx-sticky-1.2.5//ngx_http_sticky_misc.c:176:10: Error: Unused variable ‘hash’ [-Werror=unused-variable]
u_char hash[SHA_DIGEST_LENGTH];
^
/ Root/nginx-sticky-1.2.5//ngx_http_sticky_misc.c: In the function ‘ngx_http_sticky_misc_hmac_sha1’:
/root/nginx-sticky-1.2.5//ngx_http_sticky_misc.c:242:15: Error: ‘SHA_DIGEST_LENGTH’ is not declared ( Used for the first time in this function)
u_char hash[SHA_DIGEST_LENGTH];

Solution:

Modify the ngx_http_sticky_misc.c file to add #include <openssl/sha.h> and #include <openssl/md5.h> modules

[root@nginx nginx-1.12.2]# sed -i ’12a #include <openssl/sha.h>’ /root/nginx-sticky-1.2.5/ngx_http_sticky_misc.c
[root@nginx nginx-1.12.2] # sed -i ’12a #include <openssl/md5.h>’ /root/nginx-sticky-1.2.5/ngx_http_sticky_misc.c

Recompile:

[root@nginx nginx-1.12.2]# make && make install

3.6 nginx command global execution settings

[root@nginx bin]# cd /usr/local/nginx/sbin/
[root@nginx sbin]# ln -s /usr/local/nginx/sbin/nginx /usr/local/bin/nginx

4. Nginx related commands

4.1 version view

[root@nginx ~]# nginx -v
nginx version: nginx/1.12.2

4.2 Viewing Loaded Modules

[root@nginx ~]# nginx -V
nginx version: nginx/1.12.2
built by gcc 4.8.5 20150623 ( Red Hat 4.8.5-28) (GCC)
configure arguments: –add-module=/root/nginx -sticky-1.2.5/

4.3 Start and stop command

4.3.1 Starting

[root@nginx nginx-1.12.2]# nginx

4.3.2 Stop

[root@nginx nginx-1.12.2]# nginx -s stop
[root@nginx nginx-1.12.2]# nginx -s quit

4.3.3 Dynamic loading

[root@nginx nginx-1.12.2]# ngins -s reload

4.3.4 Testing the correctness of the configuration file nginx.conf

[root@nginx ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

Nginx -s quit: This method stops the process until the nginx process finishes processing the task and stops.
Nginx -s stop: This method is equivalent to first detecting the nginx process id and then using the kill command to force the process to be killed.

Nginx -s reload: Dynamic loading. When the configuration file nginx.conf changes, the command is dynamically loaded.

4.4 Boot from boot

Edit the /etc/rc.d/rc.local file and add a line /usr/local/nginx/sbin/nginx

[root@nginx rc.d]# cd /etc/rc.d
[root@nginx rc.d]# sed -i ’13a /usr/local/nginx/sbin/nginx’ /etc/rc.d/rc. Local
[root@nginx rc.d]# chmod u+x rc.local

5. Change the default port

Edit the configuration file /usr/local/nginx/conf/nginx.conf and change the default port 80 to 81:

[root@nginx ~]# view /usr/local/nginx/conf/nginx.conf

Load configuration:

[root@nginx ~]# nginx -s reload

6. Visit Nginx

6.1 Turn off the firewall

[root@nginx ~]# firewall-cmd –state
running
[root@nginx ~]# systemctl stop firewalld.service
[root@nginx ~]# firewall-cmd –state
not running

6.2 Accessing Nginx

Http://localhost:81

CentOS 7 deploys rsync backup server

1.1 rsync (official address http://wwww.samba.org/ftp/rsync/rsync.html)

A remote data synchronization tool that quickly synchronizes files between multiple hosts over a LAN/WAN. Rsync uses the so-called “rsync algorithm” to synchronize files between two local and remote hosts. This algorithm only transfers different parts of two files, rather than transmitting them all at once, so the speed is quite fast.

1.2rsync backup mode

1) Local data backup method

Rsync parameter The data to be backed up where the backup data is saved

2) Remote backup mode

Pull:rsync [OPTION…] [USER@]HOST:SRC… [DEST]
What is the rsync parameter to pull data from the corresponding host to pull data to save the local path
Push:rsync [OPTION…] SRC … [USER@]HOST:DEST
rsync where the local data is pushed by the local host data

3) Daemon process

Pull:rsync [OPTION…] [USER@]HOST::SRC… [DEST]
rsync parameter authenticates the user to pull data from the corresponding host. Pull data to save the local path
Push:rsync [OPTION…] SRC … [USER@]HOST::DEST
rsync parameter authenticates the location where the user will push the local host data for push data

2. Environmental preparation

[root@backup ~]# cat /etc/RedHat-release
CentOS Linux release 7.2.1511 (Core)
[root@backup ~]# uname -r
3.10.0-327.el7.x86_64
[root@backup ~]# getenforce
Disabled
[root@backup ~]# systemctl status firewalld.service
? firewalld.service – firewalld – dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
Active: inactive (dead)
[root@backup ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.0.41 netmask 255.255.255.0 broadcast 10.0.0.255
inet6 fe80::20c:29ff:fe40:1a4e prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:40:1a:4e txqueuelen 1000 (Ethernet)
RX packets 1607 bytes 355312 (346.9 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 358 bytes 47574 (46.4 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.16.1.41 netmask 255.255.255.0 broadcast 172.16.1.255
inet6 fe80::20c:29ff:fe40:1a58 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:40:1a:58 txqueuelen 1000 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 23 bytes 1698 (1.6 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 0 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 03.??rsync???????

3.1 Check if rsync is installed

[root@backup ~]# rpm -qa rsync

rsync-3.0.9-17.el7.x86_64

3.2 Writing rsync configuration files

[root@backup ~]# cat /etc/rsyncd.conf
#rsync_config
#created by fengyu 2018-3-16
uid = rsync Operator
gid = rsync User group
use chroot = no Related security
max connections = 200 Maximum number of connections
timeout = 300 Timeout
pid file = /var/run/rsyncd.pid The process number file corresponding to the process
lock file = /var/run/rsyncd.log lock file
log file = /var/log/rsyncd.log log file
[backup] module Name
path = /backup module location
ignore errors ignore error program
read only = false read only
list = false list of
hosts allowed = 172.16.1.01/24 network segment allowed accesses
deny = 0.0.0.0/32 network forbidden to access segment
Auth users = rsync_backup User that does not exist, only used for authentication
secrets file = /etc/rsync.password There is no key file when the user authenticates

3.3 Create an administrative user

[root@backup ~]# useradd -s /sbin/nologin -M rsync

3.4 Creating an Authentication User Password File

[root@backup ~]# echo “rsync_backup:123456” > /etc/rsync.password
[root@backup ~]# chmod 600 /etc/rsync.password

3.5 Create a backup directory

[root@backup ~]# mkdir /backup
[root@backup ~]# chown -R rsync.rsync /backup/

3.6 start daemon

[root@backup ~]# rsync –daemon
[root@backup ~]# netstat -lntup | grep rsync
tcp 0 0 0.0.0.0:873 0.0.0.0:* LISTEN 3286/rsync
tcp6 0 0 :::873 :::* LISTEN 3286/rsync

4. Configure the rsync daemon client (here, the NFS storage server is used as an example. In the work, the rsync server and the NFS server are matched with each other)

4.1 Creating a Password Authentication File

[root@nfs01 ~]# echo “123456” > /etc/rsync.password

[root@nfs01 ~]# chmod 600 /etc/rsync.password

4.2 Writing real-time monitoring push scripts

[root@nfs01 backup]# cat /server/scripts/inotify.sh
#!bin/bash
inotifywait -mrq –format “%w%f” -e create,close_write,delete,moved_to /data/|\
while read fy
do
rsync -az /data/ –delete rsync_backup@172.16.1.41::backup –password-file=/etc/rsync.password
done

4.3 Put the script execution command into the /etc/rc.local directory (under the CentOS 7 system, you need to execute the permissions in the /etc/rc.local directory)

[root@nfs01 ~]# echo “/usr/bin/sh /server/scripts/inotify.sh” >> /etc/rc.local

MySQL master-slave and proxy server

MySQL master-slave principle and process

principle

MySQL Replication is an asynchronous replication process (mysql5.1.7 or later is divided into asynchronous replication and semi-synchronous modes), copied from a Mysql instace (we call it Master) to another Mysql instance (we call it Slave) . Implementation of the Master and Slave The entire replication process is mainly done by three threads, two threads (Sql thread and IO thread) on the Slave side and another thread (IO thread) on the Master side.

To implement MySQL Replication, you must first open the Binary Log (mysql-bin.xxxxxx) function on the Master side, otherwise it will not be implemented. Because the entire copy process is actually the various operations recorded in the log that Slave takes the log from the Master and then executes it in its own complete sequence. Open MySQL’s Binary Log by adding the “-log-bin” parameter option during the startup of MySQL Server, or by adding the “log-bin” parameter to the mysqld parameter group in the configuration file (parameter part of the [mysqld] ID) item.

Basic process

1.Slave The IO thread above connects to the Master and requests the contents of the log after the specified location of the specified log file (or the log from the beginning);

2. After receiving the request from the IO thread of the slave, the master reads the log information after the specified location of the specified log according to the request information through the IO thread responsible for the copy, and returns it to the IO thread of the slave. In addition to the information contained in the log, the return information includes the name of the Binary Log file on the Master side and the location in the Binary Log.

3. After receiving the information, the IO thread of the Slave writes the received log content to the end of the Relay Log file (mysql-relay-bin.xxxxxx) on the Slave end, and reads the bin-log of the Master. The file name and location are recorded in the master-info file so that the next time you read it, you can clearly tell the Master “Which location I need to start from a bin-log, please send it to me”

4.Slave’s SQL thread detects the newly added content in the Relay Log, and immediately parses the contents of the log file into executable Query statements when the Master side is actually executed, and executes the Query on its own. In this way, the same Query is actually executed on the Master side and the Slave side, so the data at both ends is exactly the same.

Several modes of MySQL replication

Starting with MySQL 5.1.12, you can do this in three modes:

– based on statement-based replication (SBR),

– row-based replication (RBR),

– mixed-based replication (MBR)

Accordingly, there are three formats for binlog: STATEMENT, ROW, MIXED. In the MBR mode, the SBR mode is the default.

Set master-slave replication mode:
log-bin=mysql-bin

#binlog_format=”STATEMENT”

#binlog_format=”ROW”

binlog_format=”MIXED”

It is also possible to dynamically modify the format of the binlog at runtime. For example
mysql> SET SESSION binlog_format = ‘STATEMENT’;

mysql> SET SESSION binlog_format = ‘ROW’;

mysql> SET SESSION binlog_format = ‘MIXED’;

mysql> SET GLOBAL binlog_format = ‘STATEMENT’;

Mysql master-slave replication configuration

Version: mysql5.7 CentOS 7.2

Scenario description:
Primary database server: 192.168.1.100, MySQL is installed, and there is no application data.
From the database server: 192.168.1.200, MySQL is already installed and there is no application data.

1 Operations on the primary server

Start mysql service
service mysqld start

Log in to the MySQL server via the command line
mysql -uroot -p’new-password’

Authorize copy permissions to the database server 192.168.1.200
mysql> GRANT REPLICATION SLAVE ON *.* to ‘rep1’@’192.168.1.200’ identified by ‘password’;

Query the status of the primary database

When configuring the slave server,
mysql> show master status;
+————————-+———- +————–+——————+————— —-+
| File| Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+————————-+——- —+————–+——————+———— ——-+
| mysql-master-bin.000001 | 154 | | | |
+————————-+- ———+————–+——————+—— ————-+

Need to pay attention here, if the query returns
mysql> show slave status;
Empty set (0.01 sec)

This is because the bin-log is not enabled, you need to modify the /etc/my.cnf file
server-id =1
log-bin=mysql-master-bin

Also need to pay attention to when modifying the file. After mysql5.7, you need to specify the server-id when you open the binlog. Otherwise, you will get an error.

2 Configuring the slave server

Modify the configuration file from the server /opt/mysql/etc/my.cnf

Change server-id = 1 to server-id = 2 and make sure the ID is not used by other MySQL services.

Start mysql service
service mysqld start

Login to manage MySQL server
mysql -uroot -p’new-password’

change master to
master_host=’192.168.1.100′,
master_user=’root’,
master_password=’mohan..’,
master_log_file=’mysql-master-bin.000001′,
master_log_pos=154;

Start the slave synchronization process
mysql> start slave after the correct execution ;

Note that there is another pit here.
Even if the start slave is successful, the master-slave copy is still failing.
1. Error message
mysql> show slave staus;

Last_IO_Error: Fatal error: The slave I/O thread stops because master and slave have Equal MySQL server UUIDs;
These UUIDs must be different for replication to work.

2. View the master-slave server_id variable
master_mysql> show variables like ‘server_id’;
+—————+- ——+
| Variable_name | Value |
+—————+——-+
| server_id | 33|
+——- ——–+——-+

slave_mysql> show variables like ‘server_id’;
+—————+——- +
| Variable_name | Value |
+—————+——-+
| server_id | 11|
+————- –+——-+
— From the above situation, the master has used a different server_id

3 from mysql , solve the fault
### view auto.cnf file
[root@dbsrv1 ~] cat /data/mysqldata/auto.cnf ### uuid
[Auto]
Server-uuid = 62ee10aa-b1f7-11e4-90ae-080 027 615 026

[dbsrv2 the root @ ~] More /data/mysqldata/auto.cnf # ### from the uuid, there really is repeated, because the cloned Virtual machine, only change server_id not
[auto]
server-uuid=62ee10aa-b1f7-11e4-90ae-080027615026

[root@dbsrv2 ~]# mv /data/mysqldata/auto.cnf /data/mysqldata/auto.cnf.bk # ##Rename the file
[root@dbsrv2 ~]# service mysql restart ### Restart mysql
Shutting down MySQL.[ OK ]
Starting MySQL.[ OK ]
[root@dbsrv2 ~]# more /data/mysqldata/auto.cnf ###Automatically generate a new auto.cnf file after reboot, ie new UUID
[auto]
server-uuid=6ac0fdae-b5d7-11e4-a9f3-0800278ce5c9

slave

[root@dbsrv1 ~]# mysql -uroot -pxxx -e “show slave status\G”|grep Running
Warning: Using a password on the command line interface can be insecure.
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it

###uuid
master_mysql> show variables like ‘server_uuid’;
+—————+————————————–+
| Variable_name | Value|
+—————+————————————–+
| server_uuid | 62ee10aa-b1f7-11e4-90ae-080027615026 |
+—————+————————————–+
1 row in set (0.00 sec)

master_mysql> show slave hosts;
+———–+——+——+———–+————————————–+
| Server_id | Host | Port | Master_id | Slave_UUID |
+———–+——+——+———–+————————————–+
|33 | | 3306 |11 | 62ee10aa-b1f7-11e4-90ae-080027615030 |
|22 | | 3306 |11 | 6ac0fdae-b5d7-11e4-a9f3-0800278ce5c9 |
+———–+——+——+———–+————————————–+

The values ??of Slave_IO_Running and Slave_SQL_Running must be YES to indicate that the status is normal.

If the application data already exists on the primary server, the following processing is required when performing the master-slave replication:
(1) The primary database performs the lock table operation, and the data is not allowed to be written again.
mysql> FLUSH TABLES WITH READ LOCK;

(2) View the status of the main database
mysql> show master status;

(3) Record the values ??of FILE and Position.
Copy the data file of the primary server (the entire /opt/mysql/data directory) to the secondary server. It is recommended to compress it through the tar archive and then transfer it to the secondary server.

(4) cancel the main database lock
mysql> UNLOCK TABLES;

3 Verify master-slave replication

Create the database first_db on the primary server
mysql> create database first_db;
Query Ok, 1 row affected (0.01 sec)

Create a table first_tb on the primary server
mysql> create table first_tb(id int(3),name char(10));
Query Ok, 1 row affected (0.00 sec)

Insert the record
mysql> insert into first_tb values ??(001, “myself”) in the table first_tb on the primary server ;
Query Ok, 1 row affected (0.00 sec)

Viewing from the server

mysql> show databases;

MySQL read and write separation configuration under CentOS 7.2
MySQL read and write separation configuration

Environment: CentOS 7.2 MySQL 5.7

Scene Description:
Database Master Primary Server: 192.168.1.100
Database Slave Slave Server: 192.168.1.200
MySQL-Proxy Dispatch Server: 192.168.1.210

The following operations are performed on the 192.168.1.210 MySQL-Proxy scheduling server.

1. Check the software package required by the system

You need to configure the EPEL YUM source
wget before installation https://mirrors.ustc.edu.cn/epel//7/x86_64/Packages/e/epel-release-7-11.noarch.rpm
rpm -ivh epel-release-7 -11.noarch.rpm
yum clean all
yum update

yum install -y gcc* gcc-c++* autoconf* automake* zlib* libxml* ncurses-devel* libmcrypt* libtool* flex* pkgconfig* libevent* glib*

2. Compile and install lua

The read-write separation of MySQL-Proxy is mainly implemented by the rw-splitting.lua script, so you need to install lua.

Lua can
download the source package from http://www.lua.org/download.html in the following way.

Search for the relevant rpm package from rpm.pbone.net
download. Fedora . RedHat .com/pub/fedora/epel/5/i386/lua-5.1.4-4.el5.i386.rpm
download.fedora.redhat.com/ Pub/fedora/epel/5/x86_64/lua-5.1.4-4.el5.x86_64.rpm

Here we recommend to use the source package to install
cd /opt/install
wget http://www.lua.org/ftp/lua-5.1.4.tar.gz
tar zvfx lua-5.1.4.tar.gz
cd lua-5.1 .4
make linux
make install
mkdir /usr/lib/pkgconfig/
cp /opt/install/lua-5.1.4/etc/lua.pc /usr/lib/pkgconfig/
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/lib/pkgconfig

Attention problem

When compiling, the problem is that there is a lack of dependencies** readline**, then readline depends on ncurses, so you must first install two software
yum install -y readline-devel ncurses-devel

3. Install and configure MySQL-Proxy

Download mysql-proxy

???http://dev.mysql.com/downloads/mysql-proxy/
wget https://downloads.mysql.com/archives/get/file/mysql-proxy-0.8.5-linux-glibc2.3-x86-64bit.tar.gz
tar zxvf mysql-proxy-0.8.5-linux-glibc2.3-x86-64bit.tar.gz
mv zxvf mysql-proxy-0.8.5-linux-glibc2.3-x86-64bit /usr/local/mysql-proxy

** Configure mysql-proxy, create the main configuration file **
cd /usr/local/mysql-proxy
mkdir lua #Create script storage directory
mkdir logs #Create log directory
cp share / doc / mysql-proxy / rw-splitting.lua . /lua #copy read and write separation configuration file
vi /etc/mysql-proxy.cnf #Create configuration file
[mysql-proxy]
user=root
#Run mysql-proxy user admin-username=proxyuser #??mysql user
admin- Password=123456 #user’s password
proxy-address=192.168.1.210:4040 #mysql-proxyRun ip and port, no port, default 4040
proxy-read-only-backend-addresses=192.168.1.200 #Specify backend from slave Read the data
proxy-backend-addresses=192.168.1.100 #Specify the backend master master write data
proxy-lua-script=/usr/local/mysql-proxy/lua/rw-splitting.lua #Specify the read-write separation configuration file Location
admin-lua-script=/usr/local/mysql-proxy/lua/admin.lua #Specify the management script
log-file=/var/log/mysql-proxy.log #log location
Log-level=info #definition log log level
daemon=true#run
keepalive=true in daemon mode #mysql-proxy crash, try to restart

There is a pit here.

The comments in the configuration file should be completely deleted, otherwise it may cause some characters that cannot be recognized.
This is not the most pit, the most pit is: even if you delete the comment, remove the extra white space, you may still report the following error:
2018-09-21 06:39:40: (critical) Key file contains key “daemon ” Which has a value that cannot be interpreted.”

2018-09-21 06:52:22: (critical) Key file contains key “keepalive” which has a value that cannot be interpreted.

The reason for the above problem is daemon=true, keepalive=true is not written now, to be changed to:
daemon=1
keepalive=1

Execute permissions to the configuration file

chmod 660 /etc/mysql-porxy.cnf
Configuring the admin.lua file

In the /etc/mysql-proxy.cnf configuration file, the management file of /usr/local/mysql-proxy/lua/admin.lua is still not created yet. So, now you need to edit and create the admin.lua file. For this version of mysql-proxy-0.8.5, I found the following admin.lua script, which is valid for this version:

vim /usr/local/mysql-proxy/lua/admin.lua
function set_error(errmsg)
proxy.response = {
type = proxy.MYSQLD_PACKET_ERR,
errmsg = errmsg or “error”
}
end
function read_query(packet)
if packet:byte() ~= proxy.COM_QUERY then
set_error(“[admin] we only handle text-based queries (COM_QUERY)”)
return proxy.PROXY_SEND_RESULT
end
local query = packet:sub(2)
local rows = { }
local fields = { }
if query:lower() == “select * from backends” then
fields = {
{ name = “backend_ndx”,
type = proxy.MYSQL_TYPE_LONG },
{ name = “address”,
type = proxy.MYSQL_TYPE_STRING },
{ name = “state”,
type = proxy.MYSQL_TYPE_STRING },
{ name = “type”,
type = proxy.MYSQL_TYPE_STRING },
{ name = “uuid”,
type = proxy.MYSQL_TYPE_STRING },
{ name = “connected_clients”,
type = proxy.MYSQL_TYPE_LONG },
}
for i = 1, #proxy.global.backends do
local states = {
“unknown”,
“up”,
“down”
}
local types = {
“unknown”,
“rw”,
“ro”
}
local b = proxy.global.backends[i]
rows[#rows + 1] = {
i,
b.dst.name, — configured backend address
states[b.state + 1], — the C-id is pushed down starting at 0
types[b.type + 1], — the C-id is pushed down starting at 0
b.uuid, — the MySQL Server’s UUID if it is managed
b.connected_clients — currently connected clients
}
end
elseif query:lower() == “select * from help” then
fields = {
{ name = “command”,
type = proxy.MYSQL_TYPE_STRING },
{ name = “description”,
type = proxy.MYSQL_TYPE_STRING },
}
rows[#rows + 1] = { “SELECT * FROM help”, “shows this help” }
rows[#rows + 1] = { “SELECT * FROM backends”, “lists the backends and their state” }
else
set_error(“use ‘SELECT * FROM help’ to see the supported commands”)
return proxy.PROXY_SEND_RESULT
end
proxy.response = {
type = proxy.MYSQLD_PACKET_OK,
resultset = {
fields = fields,
rows = rows
}
}
return proxy.PROXY_SEND_RESULT
end

** Modify the read-write separation configuration file**
vim /usr/local/mysql-proxy/lua/rw-splitting.luaif not proxy.global.config.rwsplit
proxy.global.config.rwsplit = {
min_idle_connections = 1, #default When there are more than 4 connections, the read/write separation starts, and 1
max_idle_connections = 1, #
default8 , changed to 1 is_debug = false
}
end

mysql-proxy
/usr/local/mysql-proxy/bin/mysql-proxy –defaults-file=/etc/mysql-proxy.cnf

netstat -tupln | grep 4000 #killall -9 has been started mysql-proxy #close mysql-proxy

AWS How to Copy EBS Volumes to Different Account

It is common for an organization to have multiple AWS accounts, In my opinion, it’s a best practice to have different accounts for DEV, QA, and PROD environments. One of the reasons, just in case of any security compromise your other accounts would be unaffected.

Managing multiple accounts could be a challenge as well. Recently, I published an article on Cross-account copying of EC2 Instances. I thought it would be cool to share on how to do the same with EBS volumes, so here we go.

Obtaining Target AWS Account ID

To obtain AWS account ID a simple solution is to do the following

  1. Log in to AWS console on the target account
  2. Click on the top right corner Support > Support Center
  3. Copy the AWS Account ID and paste it into your favorite notepad, we will need it later

 

 

 

Create a Snapshot of EBS Volume

  1. To create a snapshot of EBS volume, log in to AWS console and click on Volumes under EC2 > Elastic Block Store
  2. Select the volume of your choice, Right-click or choose to Create Snapshot from the Actions Menu
  3. Enter Volume description and click Create Snapshot
  4. Verify the snapshot created

 

 

 

Verify Snapshot in Target Account

  1. Login to AWS console using target account, click on the EC2 > Elastic Block Store > Snapshots
  2. Choose Private Snapshots from the filter
  3. There you go, you can create a new EBS volume in target account using the shared snapshot


How to Fix Redis CLI Error Connection Reset by Peer

Overview

Recently we faced an issue with an AWS ElastiCache Redis instance when trying to test the connections from EC2 Instance using Redis CLI, we faced the following error

$ ./redis-cli -c -h my-redis-server -p 6379 my-redis-server:6379> set a “hello” Error: Connection reset by peer

 

 

Problem

On investigation, we found that the ElastiCache Redis Instance is using Encryption in-transit and Encryption at-rest and by design, the Redis CLI is not compatible with the encryption.

 

 

 

 

 

 

Solution

The solution to test the connectivity and to use the Redis CLI with ElastiCache In-Transit encryption,  we needed to configure ‘stunnel

Stunnel is a proxy designed to add TLS encryption functionality to existing clients and servers without any changes in the programs’ code

With stunnel client would create a SSL tunnel to the Redis nodes and use redis-cli to connect through the tunnel to access data from encrypted redis nodes.

Here is how to setup everything, we are using Amazon Linux in this example but same steps should work on Redhat Linux

1. Install stunnel


$ sudo yum install stunnel  -y

2. Configure SSL tunnel for redis-cli


$ sudo vi /etc/stunnel/redis-cli.conf
 Set the following properties in redis-cli.conf file 
fips = no
setuid = root
setgid = root
pid = /var/run/stunnel.pid
debug = 7
options = NO_SSLv2
options = NO_SSLv3
[redis-cli]
client = yes
accept = 127.0.0.1:6379
connect = my-redis-server:6379

3. Start Stunnel


$ sudo stunnel /etc/stunnel/redis-cli.conf

4. Verify the tunnel is running


$ sudo netstat -tulnp | grep -i stunnel
 You might see following output from the above command 
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 1314 stunnel

5. Last is to connect to Redis cluster using Redis CLI using SSL tunnel (Yes it is connecting using localhost tunnel)


redis-cli -h localhost -p 6379

Note: To install Redis CLI on Linux check this AWS documentation

6. Run few Redis commands to see if it works



$ ./redis-cli -h localhost -p 6379
localhost:6379> set a hello
OK
localhost:6379> get a
"hello"
localhost:6379>

Hope you find this post useful, please leave a comment and let us know what topics you would like to see.

Elasticsearch cluster deployment under CentOS7.3

 

The bottom layer of Elastic is the open source library Lucene. However, you can’t use Lucene directly, you have to write your own code to call its interface. Elastic is a package of Lucene that provides an operational interface to the REST API, out of the box. The bottom layer of Elastic is the open source library. However, you can’t use Lucene directly, you have to write your own code to call its interface. Elastic is a package of Lucene that provides an operational interface to the REST API, out of the box.

First, the basic concept in ES
Cluster
Represents a cluster. There are multiple nodes in the cluster. One of them is the master node. This master node can be elected. The master and slave nodes are internal to the cluster. A concept of es is decentralization. The literal understanding is that there is no central node. This is for the outside of the cluster, because from the outside, the es cluster is logically a whole, and you communicate with any node and the whole. Es cluster communication is equivalent.

Shards
On behalf of index shards, es can divide a complete index into multiple shards. This has the advantage of splitting a large index into multiple nodes and distributing them to different nodes. Form a distributed search. The number of shards can only be specified before the index is created, and cannot be changed after the index is created.

Replica
On behalf of the index copy, es can set a copy of multiple indexes. The role of the copy is to improve the fault tolerance of the system. When a certain piece of a node is damaged or lost, it can be recovered from the copy. The second is to improve the efficiency of es query, es will automatically load balance the search request.

Recovery
Representing data recovery or data redistribution, es will re-allocate index fragments according to the load of the machine when a node joins or exits, and data recovery will be performed when the suspended node restarts.

River
A data source representing es, and a method of synchronizing data to es by other storage methods (such as databases). It is an es service that exists as a plugin. By reading the data in the river and indexing it into es, the official river has couchDB, RabbitMQ, Twitter, and Wikipedia.

Gateway
Represents the storage mode of the es index snapshot. es defaults to storing the index in memory first, and then persisting to the local hard disk when the memory is full. The gateway stores the index snapshot. When the es cluster is closed and restarted, the index backup data is read from the gateway. Es supports multiple types of gateways, including local file system (default), distributed file system, Hadoop HDFS and amazon s3 cloud storage service.

Discovery.zen
On behalf of es’ automatic discovery node mechanism, es is a p2p-based system. It first searches for existing nodes through broadcast, and then communicates between nodes through multicast protocols, and also supports peer-to-peer interaction.

Transport
Represents the internal node of es or the interaction between the cluster and the client. The default internal interaction is using tcp protocol. At the same time, it supports the transmission protocol of http protocol (json format), thrift, servlet, memcached, zeroMQ, etc. (integrated through plug-in).

Second, the deployment environment
The deployment of Elasticsearch clusters with three CentOS 7.3s requires index fragmentation when deploying Elasticsearch clusters. The following is a brief introduction to index sharding.

system Node name IP
CentOS7.3 Els1 172.18.68.11
CentOS7.3 Els2 172.18.68.12
CentOS7.3 Els3 172.18.68.13
An index in an ES cluster may consist of multiple shards, and each shard can have multiple copies. By dividing a single index into multiple shards, we can handle large indexes that cannot be run on a single server. Simply put, the size of the index is too large, causing efficiency problems. The reason you can’t run is probably memory or storage. Since each shard can have multiple copies, you can increase the load capacity of the query by assigning copies to multiple servers.

Third, deploy Elasticsearch cluster
1. Install JDK
Elasticsearch is based on Java development and is a Java program that runs in Jvm, so the first step is to install JDK.

yum install -y java-1.8.0-openjdk-devel
2. Download elasticsearch
Https://artifacts.elastic.co/downloads/elasticsearch/ is the official site of ELasticsearch. If you need to download the latest version, you can download it from the official website. It can be downloaded to a local computer and then imported into CentOS, or it can be downloaded directly from CentOS.

wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.0.1.rpm
3. Configuration directory
After the installation is complete, many files will be generated, including configuration file log files, etc. The following are the most important configuration file paths.

/etc/elasticsearch/elasticsearch.yml # els
/etc/elasticsearch/jvm.options # JVM
/etc/elasticsearch/log4j2.properties
/var/lib/elasticsearch
4. Create a directory for storing data and logs
The data file will grow rapidly with the system running, so the default log file and data file path can not meet our needs, then manually create the log and data file path, you can use NFS, you can use Raid, etc. to facilitate future management and Expansion

mkdir /els/{log,date}
chown -R elasticsearch.elasticsearch /els/*
5. Cluster configuration
The most important cluster configuration is two node.nameand network.hosteach node must be unreasonable. Among them node.nameis the node name mainly in Elasticsearch’s own log to distinguish each node information.
discovery.zen.ping.unicast.hostsIt is the node information in the cluster. You can use the IP address and you can use the host name (you must be able to resolve it).

vim /etc/elasticsearch
cluster.name: aubin-cluster
node.name: els1

path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch

network.host: 192.168.0.1
http.port: 9200

discovery.zen.ping.unicast.hosts: [“172.18.68.11”, “172.18.68.12”,”172.18.68.13″]

discovery.zen.minimum_master_nodes: 2
6.JVM configuration
Since Elasticsearch is developed in Java, you can /etc/elasticsearch/jvm.optionsset the JVM settings through a configuration file. If there is no special requirement, you can press the default.
However, there are still two of the most important minimum memory -Xmx1gwith the -Xms1gJVM. If it is too small, it will cause Elasticsearch to stop as soon as it starts. Too slow to slow down the system itself

vim /etc/elasticsearch/jvm.options
-Xms1g # JVM
-Xmx1g
7. Start Elasticsearch
Since launching Elasticsearch will automatically start daemon-reload, the last item can be omitted.

systemctl enable elasticsearch.service
systemctl start elasticsearch
systemctl daemon-reload
8. Testing
Elasticsearch has directly heard the http interface, so you can view some cluster-related information directly using the curl command.

You can use the curl command to get information about the cluster.

_cat stands for viewing information
The nodes are for viewing node information, the default will be displayed as one line, so use the knife? Preety to make the information better display
?preety makes the output information more friendly display
curl -XGET ‘http://172.18.68.11:9200/_cat/nodes?pretty’
172.18.68.12 18 68 0 0.07 0.06 0.05 mdi – els2
172.18.68.13 25 67 0 0.01 0.02 0.05 mdi * els3
172.18.68.11 7 95 0 0.02 0.04 0.05 mdi – els1
If you want to see more about cluster information, current node statistics, etc., you can use the following command to get all the information you can view.

curl -XGET ‘http://172.18.68.11:9200/_cat?pretty’

apache redirect

Create your own short links with the mod_rewrite feature of the Apache HTTP server.

A long time ago, people started sharing links on Twitter. The 140-character limit means that the URL may consume most (or all) of a tweet, so people use URLs to shorten the service. In the end, Twitter added a built-in URL shortening service ( t.co ).

The number of characters is not important now, but there are other reasons to shorten the link. First, shortening the service can provide analytics—you can see the popularity of the links you share. It also simplifies making URLs that are easy to remember. For example, bit.ly/INtravel is easier to remember than https://www.in.gov/ai/appfiles/dhs-countyMap/dhsCountyMap.html . If you want to share a link in advance, but you don’t know the final address, then the URL shortening service can come in handy. .

As with any technology, URL shortening services are not all positive. By blocking the final address, shortened links can be used to point to malicious or offensive content. However, if you go online, the URL shortening service is a useful tool.

We previously posted an article on shortening the service on the website , but maybe you want to run some shortened services supported by simple text files. In this article, we’ll show you how to set up your own URL shortening service using the mod_rewrite feature of the Apache HTTP server. If you are not familiar with the Apache HTTP server, check out David Both ‘s article on installing and configuring it.

Create a VirtualHost
In this tutorial, I assume that you have purchased a cool domain name that you specifically use for the URL shortening service. For example, my website is funnelfiasco.com , so I bought funnelfias.co for my URL shortening service (well, it’s not very short, but it can satisfy my vanity). If you are not running the shortened service as a separate domain, skip to the next section.

The first step is to set up the VirtualHost that will be used for the URL shortening service. For more information on VirtualHost, see the article by David Both . This step only takes a few lines:

<VirtualHost *:80>
ServerName rmohan.com
</VirtualHost>

Create a rewrite rule
This service uses the HTTPD rewrite engine to rewrite the URL. If you created VirtualHost in the section above, the following configuration jumps to your VirtualHost section. Otherwise jump to the server’s VirtualHost or primary HTTPD configuration.

RewriteEngine on
RewriteMap shortlinks txt:/data/web/shortlink/links.txt
RewriteRule^/(.+)$ ${shortlinks:$1}[R=temp,L]
The first line just enables the rewrite engine. The second line builds a short link mapping in a text file. The path above is just an example. You need to use a valid path on your system (make sure it can be read by a user account running HTTPD). The last line rewrites the URL. In this case, it accepts any characters and looks them up in the rewrite map. You may want to use a specific string when rewriting. For example, if you want all shortened links are “slX” (where X is a number), then the above (.+)is replaced (sl\d+).

I am using a temporary redirect (HTTP 302) here. This will allow me to update the target URL later. If you want short links to always point to the same destination, you can use a permanent redirect (HTTP 301). By permanentreplacing the third row temp.

Build your map
Edit the configuration file RewriteMapspecifies the file line. The format is a space-separated key-value store. Put a link on each line:

osdc https://opensource.com/users/bcotton
twitter https://twitter.com/funnelfiasco
swody1 https://www.spc.noaa.gov/products/outlook/day1otlk.html

Restart HTTPD
The final step is to restart the HTTPD process. This is done by systemctl restart httpdsimilar command or completed (commands and daemons names may differ due to release). Your link shortening service is now up and running. There is no need to restart the web server when you are ready to edit the map. All you have to do is save the file and the web server will get the difference.

future career
This example gives you a basic URL shortening service. If you want to develop your own management interface as a learning project, it can be a good starting point. Or you can use it to share easy-to-remember links to URLs that are easy to forget.

GC Details

Third, the option parameters explain
1, heap size settings
1 -Xmx3550m -Xms3550m -Xmn2g -Xss128k

-Xmx 3550m: Set the maximum available memory of the JVM to 3550M.

-Xms 3550m: Set the JVM initial memory to 3550m. This value can be set to be the same as -Xmx to avoid the JVM reallocating memory after each garbage collection.

-Xmn 2g: Set the young generation size to 2G. The entire heap size = young generation size + age generation size + permanent generation size. The permanent generation has a fixed size of 64m, so increasing the young generation will reduce the size of the old generation. This value has a great impact on system performance. Sun officially recommends 3/8 of the entire heap.

-Xss 128k: Set the stack size for each thread . After JDK 5.0, the stack size of each thread is 1M, and the previous stack size of each thread is 256K. The memory size required for more application threads is adjusted. Under the same physical memory, reducing this value can generate more threads. However, the operating system has a limit on the number of threads in a process, and cannot be generated indefinitely. The empirical value is around 3000~5000.

2 -XX:NewRatio=4 -XX:SurvivorRatio=4 -XX:MaxPermSize=16m -XX:MaxTenuringThreshold=0

-XX:NewRatio =4: Set the ratio of the young generation (including Eden and the two Survivor areas) to the old generation (remove the permanent generation). Set to 4, the ratio of young to old generation is 1:4, and younger generation is 1/5 of the whole stack.

-XX:SurvivorRatio =4: Set the size ratio of the Eden area to the Survivor area in the young generation . Set to 4, the ratio of the two Survivor areas to an Eden area is 2:4, and one Survivor area accounts for 1/6 of the entire young generation.

-XX:PermSize : Sets the permanent value (perm gen) initial value. The default is 1/64 of physical memory.

-XX:MaxPermSize : Sets the maximum value of the persistent generation. 1/4 of physical memory.

– XX: MaxTenuringThreshold =0: Set the maximum age of garbage . If set to 0, the young generation object does not go through the Survivor area and directly enters the old generation. For applications with more old generations, efficiency can be improved. If this value is set to a larger value, the younger generation object will be replicated multiple times in the Survivor area, which will increase the survival time of the younger generation of the object and increase the generalization of recycling in the younger generation.

2, recycler selection
(1) Throughput priority parallel collector

1 -XX:+UseParallelGC -XX:ParallelGCThreads=20

-XX:+UseParallelGC : Select the garbage collector as a parallel collector . This configuration is only valid for younger generations . In the above configuration, the young generation uses concurrent collection, while the old generation still uses serial collection.

-XX:ParallelGCThreads =20: Configure the number of threads in the parallel collector , that is: how many threads are garbage collected together. This value is preferably configured to be equal to the number of processors.

2 -XX:+UseParallelOldGC

-XX:+UseParallelOldGC : Configures the old generation garbage collection method to be collected in parallel . JDK 6.0 supports parallel collection of old generations.

3 -XX:MaxGCPauseMillis=100

-XX:MaxGCPauseMillis =100: Set the maximum time for each young generation garbage collection . If this time is not met, the JVM will automatically adjust the young generation size to meet this value.

4 -XX:+UseAdaptiveSizePolicy

-XX:+UseAdaptiveSizePolicy : When this option is set, the parallel collector will automatically select the size of the young generation area and the corresponding proportion of the Survivor area to achieve the minimum corresponding time or collection frequency specified by the target system. This value is recommended when using the parallel collector. , always open.

(2) Response time priority concurrent collector

1 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC

-XX:+UseConcMarkSweepGC : Set the old generation to concurrent collection . After configuring this in the test, the configuration of -XX:NewRatio=4 is invalid, and the reason is unknown. Therefore, at this time, the size of the young generation is best set with -Xmn.

-XX:+UseParNewGC : Set the young generation to collect in parallel. Can be used simultaneously with CMS collection. JDK5.0 or above, the JVM will be set according to the system configuration, so there is no need to set this value.

2 -XX:CMSFullGCsBeforeCompaction=5 -XX:+UseCMSCompactAtFullCollection

-XX:CMSFullGCsBeforeCompaction : Since the concurrent collector does not compress or organize the memory space, it will generate “fragmentation” after running for a period of time, which reduces the running efficiency. This value sets how many times the GC is run to compress and organize the memory space.

-XX:+UseCMSCompactAtFullCollection : Opens the compression of the old generation. May affect performance, but can eliminate fragmentation

3. Auxiliary information
The JVM provides a number of command line arguments to print information for debugging purposes. There are mainly the following:

1 -XX:+PrintGC

Output form:

[GC 118250K->113543K (130112K), 0.0094143 secs]

[Full GC 121376K->10414K (130112K), 0.0650971 secs]

2 -XX:+PrintGCDetails

Output form:

[GC [DefNew: 8614K->781K (9088K), 0.0123035 secs] 118250K->113543K (130112K), 0.0124633 secs]

[GC [DefNew: 8614K->8614K(9088K), 0.0000665 secs][Tenured: 112761K->10414K (121024K), 0.0433488 secs] 121376K->10414K (130112K), 0.0436268 secs]

3 -XX:+PrintGCTimeStamps -XX:+PrintGC:PrintGCTimeStamps can be mixed with the above two

Output form:

11.851: [GC 98328K->93620K (130112K), 0.0082960 secs]

4 -XX:+PrintGCApplicationConcurrentTime: Prints the execution time of the program before it is garbage collected. Can be mixed with the above

Output form:

Application time: 0.5291524 seconds

5 -XX:+PrintGCApplicationStoppedTime: Prints the time the program was paused during garbage collection. Can be mixed with the above

Output form:

Total time for which application threads were stopped: 0.0468229 seconds

6 -XX: PrintHeapAtGC: Print detailed stack information before and after GC

Output form:

34.702: [GC {Heap before gc invocations=7:

Def new generation total 55296K, used 52568K [0x1ebd0000, 0x227d0000, 0x227d0000)

Eden space 49152K, 99% used [0x1ebd0000, 0x21bce430, 0x21bd0000)

From space 6144K, 55% used [0x221d0000, 0x22527e10, 0x227d0000)

To space 6144K, 0% used [0x21bd0000, 0x21bd0000, 0x221d0000)

Tenured generation total 69632K, used 2696K [0x227d0000, 0x26bd0000, 0x26bd0000)

The space 69632K, 3% used [0x227d0000, 0x22a720f8, 0x22a72200, 0x26bd0000)

Compacting perm gen total 8192K, used 2898K [0x26bd0000, 0x273d0000, 0x2abd0000)

The space 8192K, 35% used [0x26bd0000, 0x26ea4ba8, 0x26ea4c00, 0x273d0000)

Ro space 8192K, 66% used [0x2abd0000, 0x2b12bcc0, 0x2b12be00, 0x2b3d0000)

Rw space 12288K, 46% used [0x2b3d0000, 0x2b972060, 0x2b972200, 0x2bfd0000)

34.735: [DefNew: 52568K->3433K (55296K), 0.0072126 secs] 55264K->6615K (124928K) Heap after gc invocations=8:

Def new generation total 55296K, used 3433K [0x1ebd0000, 0x227d0000, 0x227d0000)

Eden space 49152K, 0% used [0x1ebd0000, 0x1ebd0000, 0x21bd0000)

From space 6144K, 55% used [0x21bd0000, 0x21f2a5e8, 0x221d0000)

To space 6144K, 0% used [0x221d0000, 0x221d0000, 0x227d0000)

Tenured generation total 69632K, used 3182K [0x227d0000, 0x26bd0000, 0x26bd0000)

The space 69632K, 4% used [0x227d0000, 0x22aeb958, 0x22aeba00, 0x26bd0000)

Compacting perm gen total 8192K, used 2898K [0x26bd0000, 0x273d0000, 0x2abd0000)

The space 8192K, 35% used [0x26bd0000, 0x26ea4ba8, 0x26ea4c00, 0x273d0000)

Ro space 8192K, 66% used [0x2abd0000, 0x2b12bcc0, 0x2b12be00, 0x2b3d0000)

Rw space 12288K, 46% used [0x2b3d0000, 0x2b972060, 0x2b972200, 0x2bfd0000)

}

, 0.0757599 secs]

7 -Xloggc:filename: Used in conjunction with the above, log related log information to a file for analysis.

Fourth, common configuration summary
1, heap settings
1 -Xms: initial heap size

2 -Xmx: maximum heap size

3 -XX:NewSize=n: set the size of the young generation

4 -XX:NewRatio=n: Set the ratio of young and old generations. For example, it is 3, indicating that the ratio of young to old is 1:3, and the young generation accounts for 1/4 of the young generation.

5 -XX: SurvivorRatio=n: The ratio of the Eden area to the two Survivor areas in the young generation. Note that there are two in the Survivor area. Such as: 3, said Eden: Survivor = 3: 2, a Survivor area accounted for 1/5 of the entire young generation

6 -XX:MaxPermSize=n: Set the permanent generation size

2, collector settings
1 -XX:+UseSerialGC: Set the serial collector

2 -XX:+UseParallelGC: Set the parallel collector

3 -XX:+UseParalledlOldGC: Set parallel old generation collector

4 -XX:+UseConcMarkSweepGC: Set Concurrent Collector

3, garbage collection statistics
1 -XX:+PrintGC

2 -XX:+PrintGCDetails

3 -XX:+PrintGCTimeStamps

4 -Xloggc:filename

4, parallel collector settings
1 -XX:ParallelGCThreads=n: Sets the number of CPUs used for parallel collector collection. Collect threads in parallel.

2 -XX:MaxGCPauseMillis=n: Set the maximum pause time for parallel collection

3 -XX:GCTimeRatio=n: Set the garbage collection time as a percentage of the program runtime. The formula is 1/(1+n)

5, concurrent collector settings
1 -XX:+CMSIncrementalMode: Set to incremental mode. Applicable to single CPU situations.

2 -XX:ParallelGCThreads=n: Set the number of CPUs used by the concurrent collector collection method for parallel collection. Collect threads in parallel.

V. Summary of tuning
1, young generation size selection
1 Response time-first application: Set as large as possible until the system’s minimum response time limit (according to the actual situation). In this case, the frequency of young generation collections is also minimal. At the same time, reduce the number of people reaching the old generation.

2 throughput-priority applications: as large as possible, may reach the level of Gbit. Because there is no requirement for response time, garbage collection can be performed in parallel, and is generally suitable for applications with more than 8 CPUs.

2, the age of old generation choice
1 Response time-first application: The old generation uses the concurrent collector, so its size needs to be carefully set, generally considering some parameters such as concurrent session rate and session duration. If the heap is set small, it can cause memory fragmentation, high recovery frequency, and application pauses using traditional markup cleanup; if the heap is large, it takes longer to collect. The optimized solution generally needs to be obtained by referring to the following data:

Concurrent garbage collection information

Persistent generation concurrent collections

Traditional GC information

Proportion of time spent on recycling young and old generations

Reducing the time spent by young and old generations generally increases the efficiency of the application

2 Throughput-first applications: General throughput-first applications have a large young generation and a smaller older generation. The reason is that this way, most of the short-term objects can be recovered as much as possible, and the medium-term objects can be reduced.

3. Fragmentation problems caused by smaller heaps
Because the older collector’s concurrent collector uses the markup and cleanup algorithms, the heap is not compressed. When the collector recycles, it merges the adjacent spaces so that it can be assigned to larger objects. However, when the heap space is small, after running for a while, “fragmentation” will occur. If the concurrent collector cannot find enough space, the concurrent collector will stop and then use traditional markup and cleanup methods for recycling. If “fragmentation” occurs, you may need to do the following:

1 -XX:+UseCMSCompactAtFullCollection: Turns on compression for the old generation when using the concurrent collector.

2 -XX:CMSFullGCsBeforeCompaction=0: In the case where the above configuration is enabled, how many times the Full GC is set here, the old generation is compressed.

Six, related concepts
1, generational garbage recycling details
(1) Young (young generation)

The young generation is divided into three districts . One Eden area, two Survivor areas . Most of the objects are generated in the Eden area. When the Eden area is full, the surviving objects will be copied to the Survivor area (one of the two). When the Survivor area is full, the surviving objects in this area will be copied to another Survivor area, when the Survivor goes When it is full, the object copied from the first Survivor area and still alive at this time will be copied “Tenured”. It should be noted that the two areas of Survivor are symmetrical and have no relationship, so there may be objects copied from Eden and objects copied from the previous Survivor in the same area, and only the first one copied to the old district. The object that Survivor came over. Moreover, there is always one empty in the Survivor area.

(2) Tenured (old generation)

The old generation stores objects that survive from the young generation . In general, older generations store objects that have a long life span.

(3) Perm (persistent generation)

Used to store static files , Java classes, methods, and more. Persistent generation has no significant impact on garbage collection, but some applications may dynamically generate or call some classes, such as Hibernate, etc. In this case, you need to set a larger persistent generation space to store the new classes in the running process. The persistent generation size is set by -XX:MaxPermSize=.

2, GC type
There are two types of GC: Scavenge GC and Full GC.

(1) Scavenge GC

In general, when a new object is generated and the Eden application space fails, the Scavenge GC is triggered, the heap Eden area is GC, the non-viable objects are cleared, and the surviving objects are moved to the Survivor area. Then organize the two areas of Survivor.

(2) Full GC

Organize the entire heap , including Young, Tenured, and Perm. Full GC is slower than the Scavenge GC, so you should minimize the Full GC . The Full GC may be caused by the following reasons:

Tenured is filled
Perm domain is filled
System.gc() is called to be called
Dynamic change of Heap’s domain allocation strategies after the last GC
3, garbage collector
There are three main types of collectors: serial collectors, parallel collectors, and concurrent collectors.

(1) Serial collector

Use single-threaded processing of all garbage collection work, because it does not require multi-threaded interaction, so it is more efficient. However, the advantages of multiprocessors cannot be used, so this collector is suitable for single processor machines. Of course, this collector can also be used on multiprocessor machines with small data volumes ( around 100M ). It can be opened with -XX:+UseSerialGC .

(2) Parallel collector

Parallel garbage collection for younger generations can reduce garbage collection time. Generally used on multi-threaded multiprocessor machines. Open with -XX:+UseParallelGC . The parallel collector was introduced in the J6SE5.0 sixth 6 update, and was enhanced in Java SE 6.0 – it can be collected in parallel for older generations. If the old generation does not use concurrent collection, it uses single-threaded garbage collection , which will restrict the expansion capability. Open with -XX:+UseParallelOldGC .
Use -XX:ParallelGCThreads=Set the number of threads for parallel garbage collection . This value can be set equal to the number of machine processors .
This collector can be configured as follows:
Maximum garbage collection pause: Specify the maximum pause time for garbage collection, specified by -XX:MaxGCPauseMillis= . In milliseconds. If this value is specified, the heap size and garbage collection related parameters are adjusted to the specified value. Setting this value may reduce the throughput of your application.
Throughput: The ratio of throughput to garbage collection time and non-garbage recovery time is set by -XX:GCTimeRatio= , and the formula is 1/(1+N) . For example, when -XX:GCTimeRatio=19, it means 5% of the time is used for garbage collection. The default is 99, which is 1% of the time for garbage collection.
(3) Concurrent collector

It can guarantee that most of the work is carried out concurrently (the application does not stop), and garbage collection is only suspended for a small amount of time. This collector is suitable for medium and large-scale applications with high response time requirements. Open with -XX:+UseConcMarkSweepGC .

The concurrent collector mainly reduces the pause time of the old generation. He uses a separate garbage collection thread to track the reachable objects without stopping the application. In each old generation garbage collection cycle, the concurrent collector will briefly pause the entire application at the beginning of the collection, and will pause again during the collection. The second pause will be slightly longer than the first one, during which multiple threads will perform garbage collection at the same time.
The concurrent collector uses the processor for a short pause . On a system with N processors, the concurrent collection part is recovered using K/N available processors, typically 1<=K<=N/4 .
Using a concurrent collector on a host with only one processor, a shorter pause can also be achieved by setting to incremental mode .
Floating garbage : Since garbage is collected while the application is running, some garbage may be generated when the garbage collection is completed, which results in “Floating Garbage”, which needs to be recycled in the next garbage collection cycle. Therefore, concurrent collectors typically require 20% of the reserved space for these floating garbage.
Concurrent Mode Failure : The concurrent collector collects when the application is running, so you need to ensure that the heap has enough space for the program to use during the garbage collection. Otherwise, the garbage collection is not completed and the heap space is full. In this case, “concurrency mode failure” will occur, and the entire application will be suspended for garbage collection.
Start Concurrent Collector : Because concurrent collection is collected while the application is running, you must ensure that there is enough memory space for the program to use before the collection is complete, otherwise “Concurrent Mode Failure” will occur. Start concurrent collection by setting -XX:CMSInitiatingOccupancyFraction= Specifying how many remaining heaps there are
(4) Summary

1 serial processor:

— Applicable situation: The data volume is relatively small (about 100M) ; the application under single processor and no response time.

— Disadvantages: only for small applications

2 parallel processor:

— Applicable situation: “High requirements for throughput” , multi-CPU, medium and large-scale applications that do not require application response time. Examples: background processing, scientific computing.

— Disadvantages: Application response time may be longer

3 concurrent processor:

— Applicable situation: “High requirements for response time” , multi-CPU, medium and large-scale applications with high requirements on application response time. For example: web server / application server, telecommunications exchange, integrated development environment.

4, the basic recovery algorithm
(1) Reference Counting

Older recycling algorithm. The principle is that this object has a reference, which is to increment a count, and to delete a reference to reduce a count. In garbage collection, only objects with a count of 0 are collected. The most deadly of this algorithm is the inability to handle circular references.

(2) Mark-Sweep (Mark-Sweep)

This algorithm is executed in two phases. The first stage marks all referenced objects starting from the reference root node, and the second stage traverses the entire heap, clearing the unmarked objects. This algorithm needs to pause the entire application and, at the same time, generate memory fragmentation.

(3) Copying

This algorithm divides the memory space into two equal regions, using only one of the regions at a time. In garbage collection, traverse the current usage area and copy the object in use to another area. The secondary algorithm only processes the objects in use at a time, so the copying cost is relatively small, and the corresponding memory can be sorted after copying in the past, but the “fragmentation” problem occurs. Of course, the shortcoming of this algorithm is also obvious, that is, it requires twice the memory space.

(4) Mark-Compact

This algorithm combines the advantages of both the “mark-clear” and “copy” algorithms. It is also divided into two phases. The first phase marks all referenced objects from the root node. The second phase traverses the entire heap, clears the unlabeled objects and “compresses” the surviving objects into one of the heaps, and discharges them in order. This algorithm avoids the “flag-clear” fragmentation problem and also avoids the space problem of the “copy” algorithm.

(5) Incremental Collecting

Implement a garbage collection algorithm that performs garbage collection while the application is running. I don’t know why the collector in JDK 5.0 does not use this algorithm.

(6) Generational Collecting

Based on the garbage collection algorithm after analyzing the life cycle of the object. The objects are divided into young, old, and permanent generations, and different algorithms (one of the above methods) are used to recover objects of different life cycles. The current garbage collector (starting with J2SE 1.2) uses this algorithm.

COPY and ADD commands in Dockerfile

COPY and ADD commands in Dockerfile

Two very similar commands COPY and ADD are provided in the Dockerfile. This article attempts to explain the basic functions of these two commands, as well as their similarities and differences, and then summarize their respective suitable application scenarios.

Build context concept
When you create a mirror from a Dockerfile using the docker build command, a build context is generated. The so-called build context is the collection of files in the path specified by the PATH or URL of the docker build command. Any file in the context can be referenced during the image build process, such as the COPY and ADD commands we will introduce, to reference the files in the context.

By default, the docker build -t testx . command in the command indicates that the build context is the current directory. Of course we can specify a directory as the context, such as the following command:

$ docker build -t testx /home/mohan/hc

We specify the /home/mohan/hc directory as the build context. By default, docker will use the Dockerfile found in the root of the context.

The COPY and ADD commands cannot copy local files outside the context.
For COPY and ADD commands, if you want to copy a local file to an image, the local file must be a file in the context directory.
In fact, this is a good explanation, because when the build command is executed, the docker client will send all the files in the context to the docker daemon . Considering that the docker client and the docker daemon are not on the same machine,

the build command can only get the file from the context. If we reference a file that is not in the context in the COPY and ADD commands of the Dockerfile, we receive an error similar to the following:

Work with WORKDIR

The WORKDIR command configures the working directory for subsequent commands such as RUN, CMD, COPY, and ADD. After the WORKDIR command is set, the relative path in the next COPY and ADD commands is the path specified relative to WORKDIR. For example, we add the following command to the Dockerfile:

WORKDIR /app
COPY checkredis.py .

Then build a container image named testx and run a container to view the file path:

The checkredis.py file is copied to the WORKDIR /app directory.

The simplicity of the COPY command
If you just copy the local file to the container image, the COPY command is the most appropriate. The format of the command is:
COPY <src> <dest>

In addition to specifying the full file name, the COPY command also supports Go-style wildcards, such as:

COPY check* /testdir/ # Copy all files at the beginning of
check COPY check?.log /testdir/ # ? is a placeholder for a single character, such as matching file check1.log

For directories, the COPY and ADD commands have the same characteristics: only copy the contents of the directory and not the directory itself. For example, we add the following command to the Dockerfile:

WORKDIR /app
COPY mohandir .

The structure of the mohandir directory is as follows:

There are only file1 and file2, and there is one less directory mohandir. If you want file1 and file2 to be saved in the mohandir directory, you need to specify the name of the directory in the target path, for example:

WORKDIR /app
COPY mohandir ./mohandir

One use of the COPY command from the ADD command is in a multistage scenario. For an introduction and usage of multistage, please refer to the author’s article ” multi-stage in Dockerfile “. In the multistage usage, you can use the COPY command to copy the product from the previous stage to another image, such as:

FROM golang: 1.7.3
WORKDIR /go/src/github.com/sparkdevo/href-counter/
RUN go get -d -v golang.org/x/net/html
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux Go build -a -installsuffix cgo -o app .

FROM alpine:latest
RUN apk –no-cache add ca-certificates
WORKDIR /root/
COPY –from=0 /go/src/github.com/sparkdevo/href-counter/app .
CMD [“./app”]

This code is referenced in the article ” multi-stage in Dockerfile “, where the COPY command copies the product of the previous stage build into the current image by specifying the –from=0 parameter.

The ADD command can also do other things.
The format of the ADD command is the same as the COPY command, which is also:
ADD <src> <dest>

In addition to the fact that it can’t be used in multistage scenarios, the ADD command can do all the functions of the COPY command, and it can also do two cool features:

Extract the compressed files and add them to the image
Copy files from url to image
Of course, these features also make the ADD command more complicated and less intuitive than the COPY command.

Extract the compressed files and add them to the image.
If we have a compressed file package, we need to add the files from this compressed package to the image. Do you need to unpack the package and then execute the COPY command? Of course not needed! We can do this once with the ADD command:

WORKDIR /app
ADD mohandir.tar.gz .

This should be the best use case for the ADD command!

Copying files from url to images
is a much more cool usage! However, in the best practices of the official documentation of docker , it is strongly recommended not to use this! ! The docker officially recommends that when we need to copy files from a remote location, it is best to use the curl or wget commands instead of the ADD command. The reason is that when using the ADD command, more mirror layers are created, and of course the size of the image will be larger (the two pieces of code below are from the docker official documentation):

ADD http://example.com/big.tar.xz /usr/src/things/
RUN tar -xJf /usr/src/things/big.tar.xz -C /usr/src/things
RUN make -C / Usr/src/things all

If you use the following command, not only does the number of layers in the image decrease, but the big.tar.xz file is also not included in the image:

RUN mkdir -p /usr/src/things \
&& curl -SL http://example.com/big.tar.xz \
| tar -xJC /usr/src/things \
&& make -C /usr/src/things All

Well, it seems that the ADD command is only needed when extracting compressed files and adding them to the image!

Tips for speeding up image construction
When using the COPY and ADD commands, we can use some tricks to speed up the mirror build process. For example, put the copy operation of the files that are least likely to change in the lower mirror layer, so that the cache generated by the previous build will be used when rebuilding the image. For example, the author needs to use the following files when building a mirror:

As shown in the figure above, the second step and the third step do not rebuild the mirror layer, but use the previous cache. From the fourth step, the mirror layer is rebuilt. When the file size is large and the number of files is large, especially when you need to perform operations such as installation, such a design is still very obvious for the speed of the build. So we should try to choose the Dockerfile method that can use the cache.

to sum up
When you first see the COPY and ADD commands, you can’t help wondering. But after analysis, you will find that the COPY command is designed for the most basic usage, with clear concepts and simple operation. The ADD command is basically a superset of the COPY command (except for the multistage scenario), which allows for some convenient and cool copy operations. The ADD command adds complexity to its use, such as copying compressed files from urls. I hope this article can solve everyone’s doubts about the COPY and ADD commands in the Dockerfile