Linux 保护进程不被OOM Killer

From: https://blog.csdn.net/flysqrlboy/article/details/89011635

最近在预发环境上有一个重要的进程隔三差五就被OOM Killer干掉(通过查看CentOS系统日志/var/log/messages揪出来是OOM Killer干的)。该机器上跑着各种进程,内存是有些吃紧。这当然可以通过加大机器内存或者迁走某些进程来解决。但一时又没有多余的机器和内存资源,只能自己动手丰衣足食了(资源短缺确实是更能激发人去思考更优更节省的方案)。现在我要解决的是如下两个问题:

为什么被OOM Killer干掉的是这个进程而不是其他的?
能保护某个进程不被OOM Killer 干掉吗?
Surviving the Linux OOM Killer》一文正是对上面两个问题的介绍。

基本概念:

Linux 内核有个机制叫OOM killer(Out Of Memory killer),该机制会监控那些占用内存过大,尤其是瞬间占用内存很快的进程,然后防止内存耗尽而自动把该进程杀掉。内核检测到系统内存不足、挑选并杀掉某个进程的过程可以参考内核源代码linux/mm/oom_kill.c,当系统内存不足的时候,out_of_memory()被触发,然后调用select_bad_process()选择一个”bad”进程杀掉。如何判断和选择一个”bad进程呢?linux选择”bad”进程是通过调用oom_badness(),挑选的算法和想法都很简单很朴实:最bad的那个进程就是那个最占用内存的进程。

如何查看:

grep "Out of memory" /var/log/messages

查看系统日志方法:

运行egrep -i -r ‘killed process’ /var/log命令, 也可运行dmesg命令

sudo dmesg -T | grep "(java)" 

How does OOM Killer choose which process to kill?

Linux 内核会给每个运行中的进程分配一个叫 oom_score 的分数,它表示当系统可用内存很低时,一个进程被kill掉的可能性有多大。分数越高,越有可能被kill掉。分数值很简单:等于进程的内存占用百分比乘以10。比如一个进程占50%的内存,它的oom_score值就是 50 X 10 = 500 .
一个进程的oom_score被记录在/proc/$pid/oom_score 文件中。

Can I ensure some important processes do not get killed by OOM Killer?

OOM Killer会检查 /proc/$pid/oom_score_adj文件来调整最终的分数 (oom_score)。所以我们可以通过在这个文件中给一个大的负数,以降低该进程被选中并终止的可能性。oom_score_adj可以在-1000到1000间变化。如果你给了-1000,进程即使使用了100%的内存也不会被OOM Killer干掉。可通过下面命令修改oom_score_adj(比如设为-200):

sudo echo -200 > /proc/$pid/oom_score_adj

或者,我们可以:

echo -17 > /proc/<pid>/oom_adj

-17表示禁用OOM我们也可以对把整个系统的OOM给禁用掉:

sysctl -w vm.panic_on_oom=1sysctl -p

参数/proc/sys/vm/overcommit_memory可以控制进程对内存过量使用的应对策略
当overcommit_memory=0 允许进程轻微过量使用内存,但对于大量过载请求则不允许
当overcommit_memory=1 永远允许进程overcommit

当overcommit_memory=2 永远禁止overcommit

版权声明:本文为CSDN博主「keke_xin」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/keke_Xin/article/details/84829816

Caveats of adjusting OOM scores

警告:解决内存不足的最好办法还是增加可用内存(例如更好的硬件)或者将某些进程移到别的地方去,又或者优化代码以减少内存消耗。

oom killer理解和日志分析:知识储备

oom killer理解和日志分析:日志分析

java自动部署/启动脚本(linux)

1.jar

#!/bin/bash
#
pkg_path=/tmp
run_path=/usr
version=1.0.0
uptime=`date +"%F"`

cd $run_path

pkgs=(jar1 jar2 jar3)
for pkg in ${pkgs[@]}
do

mv $pkg-$version.jar $pkg_path/bak/$pkg-$version.jar.$uptime
cp $root_path/packages/$pkg-$version.jar $pkg-$version.jar

PID=`ps -ef|grep $pkg-$version|egrep -v grep|awk '{print $2}'`
if [ ! "$PID" = "" ]
then
kill $PID
echo "KILL $PID:"
fi

sleep 2
nohup java -Xmx128m -Xms128m -jar $pkg-$version.jar >$pkg.$uptime.out 2>&1 &

PID2=`ps -ef|grep $pkg|egrep -v grep|awk '{print $2}'`
[ $? -eq 0 ] && echo "start $pkg(Pid:$PID2) OK" || echo "start $pkg Fail"
sleep 3

done

2.war

#!/bin/bash
#
pkg_path=/tmp
run_path=/usr
uptime=`date +"%F"`

cd $run_path

pkgs=(api openapi sp pos)
for pkg in ${pkgs[@]}
do

rm -rf $pkg/webapps/ROOT
mv $pkg/webapps/ROOT.war $pkg_path/bak/$pkg.war.$uptime
cp $pkg_path/$pkg.war $pkg/webapps/ROOT.war

PID=`ps -ef|grep $run_path/$pkg|egrep -v grep|awk '{print $2}'`
if [ ! "$PID" = "" ]
then
	kill -9 $PID
	echo "KILL $PID:"
fi

sleep 2

./$pkg/bin/startup.sh

PID2=`ps -ef|grep $run_path/$pkg|egrep -v grep|awk '{print $2}'`
[ $? -eq 0 ] && echo "start $pkg(Pid:$PID2) OK" || echo "start $pkg Fail"
sleep 10

done

Maven仓库理解、如何引入本地包、Maven多种方式打可执行jar包

有关MAVEN仓库的理解参见:http://blog.csdn.net/wanghantong/article/details/36427433

MAVEN依赖关系中Scope的作用

Java代码 
  1. Dependency Scope 在POM 4中,<dependency>中还引入了<scope>,它主要管理依赖的部署。目前依赖项的作用域<scope>可以使用5个值:    
  2. 在定义项目的依赖项的时候,我们可以通过scope来指定该依赖项的作用范围。scope的取值有compile、runtime、test、provided、system和import。  
  3. compile:这是依赖项的默认作用范围,即当没有指定依赖项的scope时默认使用compile。compile范围内的依赖项在所有情况下都是有效的,包括运行、测试和编译时。  
  4. runtime:表示该依赖项只有在运行时才是需要的,在编译的时候不需要。这种类型的依赖项将在运行和test的类路径下可以访问。  
  5. test:表示该依赖项只对测试时有用,包括测试代码的编译和运行,对于正常的项目运行是没有影响的。  
  6. provided:表示该依赖项将由JDK或者运行容器在运行时提供,也就是说由Maven提供的该依赖项我们只有在编译和测试时才会用到,而在运行时将由JDK或者运行容器提供。  
  7. system:当scope为system时,表示该依赖项是我们自己提供的,不需要Maven到仓库里面去找。指定scope为system需要与另一个属性元素systemPath一起使用,它表示该依赖项在当前系统的位置,使用的是绝对路径。  

 

Java代码 
  1. POM文件里面可以引用一些内置属性(Maven预定义可以直接使用)  
  2. ${basedir} 项目根目录   
  3. ${version}表示项目版本;  
  4. ${project.basedir}同${basedir};  
  5. ${project.version}表示项目版本,与${version}相同;  
  6. ${project.build.directory} 构建目录,缺省为target  
  7. ${project.build.sourceEncoding}表示主源码的编码格式;  
  8. ${project.build.sourceDirectory}表示主源码路径;  
  9. ${project.build.finalName}表示输出文件名称;  
  10. ${project.build.outputDirectory} 构建过程输出目录,缺省为target/classes  

 

如何在Maven项目中引入本地包呢?

比如我从其它项目打一个jar包,引入到现有项目中。

方法一:将待引入的包放在目录下如lib目录下,修改pom文件,加入依赖并且scope要设置为system

 

Java代码 
 <dependency>
        <groupId>org.wltea.ik-analyzer</groupId>
        <artifactId>ik-analyzer</artifactId>
        <version>3.2.8</version>
        <scope>system</scope>
        <systemPath>${project.basedir}/lib/fbcds.jar</systemPath>
    </dependency>


 上面设置完成后,运行mvn package命令执行成功。但打出来的包里面不包含lib目录和fbcds.jar这个引用的包,即打出来的包不是可执行的jar。所以个人开发的话可以使用这种方式,如果团队开发请使用方法二。

 

方法二:将待引入的jar包安装到本地repository中

1、先把待引入的jar包放在一个目录下,需要改一下包名,如fbcds.jar修改成fbcds-1.0.jar,如F:\lib目录,在命令行CD到lib目录,执行以下命令:

Java代码 
  1. mvn install:install-file -Dfile=fbcds-1.0.jar -DgroupId=fbcds -DartifactId=fbcds -Dversion=1.0 -Dpackaging=jar  
  2. mvn install:install-file -Dfile=ojdbc7-1.0.jar -DgroupId=ojdbc7 -DartifactId=ojdbc7 -Dversion=1.0 -Dpackaging=jar  

 2、修改项目pom文件加入包对应的依赖

 

Java代码 

 

<dependencies>  

    <dependency>  

      <groupId>log4j</groupId>  

      <artifactId>log4j</artifactId>  

      <version>1.2.17</version>  

    </dependency>  

    <dependency>  

      <groupId>fbcds</groupId>  

      <artifactId>fbcds</artifactId>  

      <version>1.0</version>  

    </dependency>  

    <dependency>   

      <groupId>ojdbc7</groupId>  

      <artifactId>ojdbc7</artifactId>  

      <version>1.0</version>   

    </dependency>  

  </dependencies>  

 上面的fbcds和ojdbc7就是新加的引用包的依赖。

 

MAVEN如何打可执行的JAR包

前提条件:已成功将待引入的jar包安装到本地repository中

方法一、使用maven-shade-plugin插件打可执行的jar包

插件查找链接:http://maven.apache.org/plugins/

1、测试类代码

 

Java代码:

package com.lwf.test;  

  

import java.sql.Connection;  

import java.sql.DriverManager;  

import java.sql.ResultSet;  

import java.sql.SQLException;  

import java.sql.Statement;  

  

import com.eclink.fbcis.store.StoreDao;  

  

public class TestClass {  

    public static void main(String[] args) {  

        …….

    }  

}  

 上面类中引用到了fbcds和ojdbc7包的内容。

2、对应pom文件

Java代码 

<project xmlns=“http://maven.apache.org/POM/4.0.0” xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=“http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd”>  

  <modelVersion>4.0.0</modelVersion>  

  <groupId>222</groupId>  

  <artifactId>222</artifactId>  

  <version>0.0.1-SNAPSHOT</version>  

  <name>222</name>  

  <dependencies>  

    <dependency>  

      <groupId>log4j</groupId>  

      <artifactId>log4j</artifactId>  

      <version>1.2.17</version>  

    </dependency>  

    <dependency>  

      <groupId>fbcds</groupId>  

      <artifactId>fbcds</artifactId>  

      <version>1.0</version>  

    </dependency>  

    <dependency>   

      <groupId>ojdbc7</groupId>  

      <artifactId>ojdbc7</artifactId>  

      <version>1.0</version>   

    </dependency>  

  </dependencies>  

    <build>  

        <plugins>  

            <plugin>  

                <groupId>org.apache.maven.plugins</groupId>  

                <artifactId>maven-shade-plugin</artifactId>  

                <version>2.4.3</version>  

                <executions>  

                    <execution>  

                        <phase>package</phase>  

                        <goals>  

                            <goal>shade</goal>  

                        </goals>  

                        <configuration>  

                            <transformers>  

                                <transformer implementation=“org.apache.maven.plugins.shade.resource.ManifestResourceTransformer”>  

                                    <mainClass>com.lwf.test.TestClass</mainClass>  

                                </transformer>  

                            </transformers>  

                        </configuration>  

                    </execution>  

                </executions>  

            </plugin>  

        </plugins>  

    </build>  

  

</project>  

 在eclipse中右键项目run as 选择Maven package,可看打包的target目录内容:



 比较两个包内容:



 original-MavenPackage-0.0.1-SNAPSHOT.jar中没有主清单属性是执行不了的。

 参见:http://www.mkyong.com/maven/create-a-fat-jar-file-maven-shade-plugin/

方法二、使用maven-assembly-plugin插件打可执行的jar包

测试类与方法一中一样,只是pom不一样,pom文件如下:

Java代码 

<project xmlns=“http://maven.apache.org/POM/4.0.0” xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=“http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd”>  

  <modelVersion>4.0.0</modelVersion>  

  <groupId>com.lwf.MavenPackage</groupId>  

  <artifactId>MavenPackage</artifactId>  

  <version>0.0.1-SNAPSHOT</version>  

  <name>MavenPackage</name>  

  <dependencies>  

    <dependency>  

      <groupId>log4j</groupId>  

      <artifactId>log4j</artifactId>  

      <version>1.2.17</version>  

    </dependency>  

    <dependency>  

      <groupId>fbcds</groupId>  

      <artifactId>fbcds</artifactId>  

      <version>1.0</version>  

    </dependency>  

    <dependency>   

      <groupId>ojdbc7</groupId>  

      <artifactId>ojdbc7</artifactId>  

      <version>1.0</version>   

    </dependency>  

  </dependencies>  

    <build>  

        <plugins>          

<!– 使用 maven-Assembly-plugin插件打可执行包–>  

            <plugin>  

                <groupId>org.apache.maven.plugins</groupId>  

                <artifactId>maven-assembly-plugin</artifactId>  

                <version>2.6</version>  

                <configuration>  

                    <!– get all project dependencies –>  

                    <descriptorRefs>  

                        <descriptorRef>jar-with-dependencies</descriptorRef>  

                    </descriptorRefs>  

                    <!– MainClass in mainfest make a executable jar –>  

                    <archive>  

                      <manifest>  

                        <mainClass>com.lwf.test.TestClass</mainClass>  

                      </manifest>  

                    </archive>  

                </configuration>  

                <executions>  

                  <execution>  

                    <id>make-assembly</id>  

                    <phase>package</phase>   

                    <goals>  

                        <goal>single</goal>  

                    </goals>  

                  </execution>  

                </executions>  

            </plugin>  

        </plugins>  

    </build>  

  

</project>  

 修改完pom后,在eclipse中右键项目run as 选择Maven package,可看打包的target目录内容:
 两个jar文件比较:



 

 

 参见:http://www.mkyong.com/maven/create-a-fat-jar-file-maven-assembly-plugin/

方法三、使用onejar-maven-plugin插件打可执行的jar包

测试类与方法一中一样,只是pom不一样,pom文件如下:

Java代码 

<project xmlns=“http://maven.apache.org/POM/4.0.0” xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=“http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd”>  

  <modelVersion>4.0.0</modelVersion>  

  <groupId>com.lwf.MavenPackage</groupId>  

  <artifactId>MavenPackage</artifactId>  

  <version>0.0.1-SNAPSHOT</version>  

  <name>MavenPackage</name>  

  <dependencies>  

    <dependency>  

      <groupId>log4j</groupId>  

      <artifactId>log4j</artifactId>  

      <version>1.2.17</version>  

    </dependency>  

    <dependency>  

      <groupId>fbcds</groupId>  

      <artifactId>fbcds</artifactId>  

      <version>1.0</version>  

    </dependency>  

    <dependency>   

      <groupId>ojdbc7</groupId>  

      <artifactId>ojdbc7</artifactId>  

      <version>1.0</version>   

    </dependency>  

  </dependencies>  

    <build>  

        <plugins>              

            <!– 使用 onejar-maven-plugin插件打可执行包–>  

            <plugin>  

                <groupId>org.apache.maven.plugins</groupId>  

                <artifactId>maven-jar-plugin</artifactId>  

                <configuration>  

                    <archive>  

                        <manifest>  

                            <mainClass>com.lwf.test.TestClass</mainClass>  

                        </manifest>  

                    </archive>  

                </configuration>  

            </plugin>  

            <plugin>  

                <groupId>com.jolira</groupId>  

                <artifactId>onejar-maven-plugin</artifactId>  

                <version>1.4.4</version>  

                <executions>  

                    <execution>  

                        <configuration>  

                            <attachToBuild>true</attachToBuild>  

                            <classifier>onejar</classifier>  

                        </configuration>  

                        <goals>  

                            <goal>one-jar</goal>  

                        </goals>  

                    </execution>  

                </executions>  

            </plugin>  

        </plugins>  

    </build>  

</project>  

打包截图如下:



 
 

参见:http://www.mkyong.com/maven/maven-create-a-fat-jar-file-one-jar-example/

上文中因googlecode中已没有onejar-maven-plugin所以另请参见下文:

http://my.oschina.net/noahxiao/blog/78241

方法四:使用maven-jar-plugin和maven-dependency-plugin打可执行包,引用的包放包外面文件夹下

其他不变,pom文件如下

Java代码 

<project xmlns=“http://maven.apache.org/POM/4.0.0” xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=“http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd”>  

  <modelVersion>4.0.0</modelVersion>  

  <groupId>com.lwf.MavenPackage</groupId>  

  <artifactId>MavenPackage</artifactId>  

  <version>0.0.1-SNAPSHOT</version>  

  <name>MavenPackage</name>  

  <dependencies>  

    <dependency>  

      <groupId>log4j</groupId>  

      <artifactId>log4j</artifactId>  

      <version>1.2.17</version>  

    </dependency>  

    <dependency>  

      <groupId>fbcds</groupId>  

      <artifactId>fbcds</artifactId>  

      <version>1.0</version>  

    </dependency>  

    <dependency>   

      <groupId>ojdbc7</groupId>  

      <artifactId>ojdbc7</artifactId>  

      <version>1.0</version>   

    </dependency>  

  </dependencies>  

    <build>  

        <plugins>  

 

<!– 方法四:使用maven-jar-plugin和maven-dependency-plugin打可执行包,引用的包放包外面文件夹下 –>  

            <plugin>  

                <groupId>org.apache.maven.plugins</groupId>  

                <artifactId>maven-jar-plugin</artifactId>  

                <configuration>  

                  <excludes>  

                    <exclude>**/log4j.properties</exclude>  

                  </excludes>  

                  <archive>  

                    <manifest>  

                    <addClasspath>true</addClasspath>  

                    <mainClass>com.lwf.test.TestClass</mainClass>  

                    <classpathPrefix>lib/</classpathPrefix>  

                    </manifest>  

                  </archive>  

                </configuration>  

            </plugin>  

  

            <!– Copy project dependency –>  

            <plugin>  

                <groupId>org.apache.maven.plugins</groupId>  

                <artifactId>maven-dependency-plugin</artifactId>  

                <version>2.5.1</version>  

                <executions>  

                  <execution>  

                    <id>copy-dependencies</id>  

                    <phase>package</phase>  

                    <goals>  

                        <goal>copy-dependencies</goal>  

                    </goals>  

                    <configuration>  

                      <!– exclude junit, we need runtime dependency only –>  

                      <includeScope>runtime</includeScope>  

                      <outputDirectory>${project.build.directory}/lib/</outputDirectory>  

                    </configuration>  

                  </execution>  

                </executions>  

            </plugin>              

        </plugins>  

    </build>  

</project>  

可以看到依赖的包拷贝到了lib目录下,打的包里没有依赖包的信息,只是简单的包,不过Manifest文件class-path要包含引用名的路径

Java代码 

 

Manifest-Version: 1.0  

Built-By: lweifeng  

Build-Jdk: 1.7.0_17  

Class-Path: lib/log4j-1.2.17.jar lib/fbcds-1.0.jar lib/ojdbc7-1.0.jar  

Created-By: Apache Maven 3.3.9  

Main-Class: com.lwf.test.TestClass  

Archiver-Version: Plexus Archiver  

 
 在以上前三种插件打包方式中,maven-shade-plugin和maven-assembly-plugin采取的是将依赖包解压再一并打到新包中,这样依赖包可能存在冲突的时候,导致运行时可能出现未知问题,而onejar-maven-plugin打包是将依赖包自动归入lib目录,不解压原包,相当于在原包基础上加壳,这样可以避免冲突的发生。第四种方法即是我们原来ant打包所使用的方法。

对于war包系统来说,有时候需要把jar包打到相关的war包中,可以使用plugin,默认将lib下的所有jar文件打包到WEB-INF/lib下。当然也是可以打包其他的文件的,诸如xml,properties等的。相关的plugin如下:

<plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.3</version>
            <configuration>
                <warName>${project.artifactId}</warName>
                <webResources>
                    <resource>
                        <directory>lib/</directory>
                        <targetPath>WEB-INF/lib</targetPath>
                        <includes>
                            <include>**/*.jar</include>
                        </includes>
                    </resource>
                </webResources>
            </configuration>
        </plugin>

centos 初始化的一些工作

1.修改IP地址

vi /etc/sysconfig/network-scripts/ifcfg-eth0

TYPE=Ethernet
BOOTPROTO=none
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
NAME=eth0
UUID=c407ed36-7926-44d6-b641-828288173482
DEVICE=eth0
ONBOOT=yes
IPADDR=192.168.154.100
PREFIX=24
GATEWAY=192.168.154.2
IPV6_PEERDNS=yes
IPV6_PEERROUTES=yes

重启network:

service network restart

2.hostname修改

uname -a 查看hostname
hostname newname 修改下,让hostname立刻生效。
vi /etc/hostname 修改原hostname为 newname
vi /etc/sysconfig/network 修改原hostname为 newname
reboot重启,uname -a 重新检查下。Done!

3. 防火墙设置

方式一: 设置firewalld

1)用现成的模板


cp /usr/lib/firewalld/services/http.xml /etc/firewalld/services/
cp /usr/lib/firewalld/services/https.xml /etc/firewalld/services/
cp /usr/lib/firewalld/services/ftp.xml /etc/firewalld/services/
cp /usr/lib/firewalld/services/mysql.xml /etc/firewalld/services/

修改public.xml, 添加以上service:

vi /usr/lib/firewalld/zones/public.xml

添加:

<service name=”http”/>
<service name=”mysql”/>
<service name=”ftp”/>
<service name=”https”/>

保存退出,并刷新:
firewall-cmd –reload

2)手动添加

##Add
firewall-cmd –permanent –zone=public –add-port=80/tcp

##Remove
firewall-cmd –permanent –zone=public –remove-port=80/tcp

##Reload
firewall-cmd –reload

命令含义:

–zone #作用域

–add-port=80/tcp #添加端口,格式为:端口/通讯协议

–permanent #永久生效,没有此参数重启后失效

其中,方法2的配置方式是间接修改/etc/firewalld/zones/public.xml文件,方法1也需要在public.xml里面新增,否则http的防火墙规则不会生效,

而且两种配置方式都需要重新载入防火墙。

方式二:关闭默认firewalls防火墙, 启用iptables防火墙(不建议)

注意: 由于centos7安装的只是iptables的核心组件,所以你还需要重新安装iptables.

关闭firewall:
systemctl stop firewalld.service #停止firewall
systemctl disable firewalld.service #禁止firewall开机启动
firewall-cmd –state #查看默认防火墙状态(关闭后显示notrunning,开启后显示running)

启用iptables防火墙(这里iptables已经安装,下面进行配置)
vi /etc/sysconfig/iptables #编辑防火墙配置文件
# sampleconfiguration for iptables service
# you can edit thismanually or use system-config-firewall
# please do not askus to add additional ports/services to this default configuration
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT[0:0]
:OUTPUT ACCEPT[0:0]
-A INPUT -m state–state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -jACCEPT
-A INPUT -i lo -jACCEPT
-A INPUT -p tcp -mstate –state NEW -m tcp –dport 22 -j ACCEPT
-A INPUT -p tcp -m state –state NEW -m tcp –dport 80 -jACCEPT
-A INPUT -p tcp -m state –state NEW -m tcp –dport 8080-j ACCEPT
-A INPUT -j REJECT–reject-with icmp-host-prohibited
-A FORWARD -jREJECT –reject-with icmp-host-prohibited
COMMIT
:wq! #保存退出

4. jdk安装

卸载系统自带openjdk组件

rpm -ga|grep java 列出已安装的组件

命令说明:

rpm   管理套件    

-qa   使用询问模式,查询所有套件

grep  查找文件里符合条件的字符串

java   查找包含java字符串的文件

可删除的组件:

java-1.7.0-openjdk-XXXXXX

删除组件:
rpm -e –nodeps java-1.7.0-openjdk-XXXXXX

验证是否删除: java -version

找不到java组件,表示已删除

安装jdk:

tar安装: tar -zxvf jdk-XXXXX.tar.gz

rpm安装:rpm -ivh jdk-XXXXX.rpm

yum安装: yum install jdk-XXXX.x86_64

设置环境变量

vi /etc/profile

在profile中添加如下内容:

#set java environment
JAVA_HOME=/usr/java/default
JRE_HOME=/usr/java/default/jre
CLASS_PATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib
PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
export JAVA_HOME JRE_HOME CLASS_PATH PATH

让修改生效:

source /etc/profile

验证JDK有效性

# java -version
[root@localhost java]java version “1.8.0_102”

从git拉取代码 并进行 maven编译

#!/bin/bash
DATE=`date +%F-%H-%M-%S`
FORK=master
TAG=0
v=版本号
WPATH=/打包根路径

#build fork-1.2.0
if [ $# = 1 ]
then
  echo "打包分支:$1"
  FORK=$1
fi

#build tag 1.2.0.release
if [ $# = 2 ]
then
  echo "打包TAG:$2"
  FORK=$1
  TAG=$2
fi

mkdir -p $WPATH/wars
#delete maven cache
rm -rf /root/.m2/repository/项目包路径


cd $WPATH
#init git
if [ ! -d "$WPATH/代码根目录" ] || [ ! -f "$WPATH/代码根目录/pom.xml" ];
then
    echo "git clone XXX项目"
    git clone http://代码路径 >/dev/null 2>&1
fi

#打包项目
cd $WPATH/代码根目录
echo "mvn install XXX项目"
git fetch origin
#build branch
if [ $TAG = 0 ]
then
  git checkout -b $FORK origin/$FORK
  git checkout $FORK
  git pull origin $FORK >/dev/null 2>&1
fi
#build tag
if [ $TAG != 0 ]
then
  git tag -l | xargs git tag -d
  git fetch -t -p -f
  git checkout $TAG
fi
#git -c core.quotepath=false checkout commitID^0 --
mvn clean install -Dmaven.test.skip=true >$WPATH/pack.log

test=`grep "BUILD SUCCESS" $WPATH/pack.log`
if [ ! "$test" = "" ];
then
\cp target/*-$v.jar $WPATH/wars/
echo "mvn OK"
else
  echo "mvn Fail"
fi

nginx配置

序言

Nginx是lgor Sysoev为俄罗斯访问量第二的rambler.ru站点设计开发的。从2004年发布至今,凭借开源的力量,已经接近成熟与完善。

Nginx功能丰富,可作为HTTP服务器,也可作为反向代理服务器,邮件服务器。支持FastCGI、SSL、Virtual Host、URL Rewrite、Gzip等功能。并且支持很多第三方的模块扩展。

Nginx的稳定性、功能集、示例配置文件和低系统资源的消耗让他后来居上,在全球活跃的网站中有12.18%的使用比率,大约为2220万个网站。

牛逼吹的差不多啦,如果你还不过瘾,你可以百度百科或者一些书上找到这样的夸耀,比比皆是。

Nginx常用功能

1、Http代理,反向代理:作为web服务器最常用的功能之一,尤其是反向代理。

这里我给来2张图,对正向代理与反响代理做个诠释,具体细节,大家可以翻阅下资料。

Nginx在做反向代理时,提供性能稳定,并且能够提供配置灵活的转发功能。Nginx可以根据不同的正则匹配,采取不同的转发策略,比如图片文件结尾的走文件服务器,动态页面走web服务器,只要你正则写的没问题,又有相对应的服务器解决方案,你就可以随心所欲的玩。并且Nginx对返回结果进行错误页跳转,异常判断等。如果被分发的服务器存在异常,他可以将请求重新转发给另外一台服务器,然后自动去除异常服务器。

2、负载均衡

Nginx提供的负载均衡策略有2种:内置策略和扩展策略。内置策略为轮询,加权轮询,Ip hash。扩展策略,就天马行空,只有你想不到的没有他做不到的啦,你可以参照所有的负载均衡算法,给他一一找出来做下实现。

上3个图,理解这三种负载均衡算法的实现

Ip hash算法,对客户端请求的ip进行hash操作,然后根据hash结果将同一个客户端ip的请求分发给同一台服务器进行处理,可以解决session不共享的问题。 

3、web缓存

Nginx可以对不同的文件做不同的缓存处理,配置灵活,并且支持FastCGI_Cache,主要用于对FastCGI的动态程序进行缓存。配合着第三方的ngx_cache_purge,对制定的URL缓存内容可以的进行增删管理。

4、Nginx相关地址

源码:https://trac.nginx.org/nginx/browser

官网:http://www.nginx.org/

Nginx配置文件结构

如果你下载好啦,你的安装文件,不妨打开conf文件夹的nginx.conf文件,Nginx服务器的基础配置,默认的配置也存放在此。

在nginx.conf的注释符号位#

nginx文件的结构,这个对刚入门的同学,可以多看两眼。

默认的config 

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}
...              #全局块

events {         #events块
   ...
}

http      #http块
{
    ...   #http全局块
    server        #server块
    { 
        ...       #server全局块
        location [PATTERN]   #location块
        {
            ...
        }
        location [PATTERN] 
        {
            ...
        }
    }
    server
    {
      ...
    }
    ...     #http全局块
}

1、全局块:配置影响nginx全局的指令。一般有运行nginx服务器的用户组,nginx进程pid存放路径,日志存放路径,配置文件引入,允许生成worker process数等。

2、events块:配置影响nginx服务器或与用户的网络连接。有每个进程的最大连接数,选取哪种事件驱动模型处理连接请求,是否允许同时接受多个网路连接,开启多个网络连接序列化等。

3、http块:可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。如文件引入,mime-type定义,日志自定义,是否使用sendfile传输文件,连接超时时间,单连接请求数等。

4、server块:配置虚拟主机的相关参数,一个http中可以有多个server。

5、location块:配置请求的路由,以及各种页面的处理情况。

下面给大家上一个配置文件,作为理解,同时也配入我搭建的一台测试机中,给大家示例。 

 
########### 每个指令必须有分号结束。#################
#user administrator administrators;  #配置用户或者组,默认为nobody nobody。
#worker_processes 2;  #允许生成的进程数,默认为1
#pid /nginx/pid/nginx.pid;   #指定nginx进程运行文件存放地址
error_log log/error.log debug;  #制定日志路径,级别。这个设置可以放入全局块,http块,server块,级别以此为:debug|info|notice|warn|error|crit|alert|emerg
events {
    accept_mutex on;   #设置网路连接序列化,防止惊群现象发生,默认为on
    multi_accept on;  #设置一个进程是否同时接受多个网络连接,默认为off
    #use epoll;      #事件驱动模型,select|poll|kqueue|epoll|resig|/dev/poll|eventport
    worker_connections  1024;    #最大连接数,默认为512
}
http {
    include       mime.types;   #文件扩展名与文件类型映射表
    default_type  application/octet-stream; #默认文件类型,默认为text/plain
    #access_log off; #取消服务日志    
    log_format myFormat '$remote_addr–$remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for'; #自定义格式
    access_log log/access.log myFormat;  #combined为日志格式的默认值
    sendfile on;   #允许sendfile方式传输文件,默认为off,可以在http块,server块,location块。
    sendfile_max_chunk 100k;  #每个进程每次调用传输数量不能大于设定的值,默认为0,即不设上限。
    keepalive_timeout 65;  #连接超时时间,默认为75s,可以在http,server,location块。

    upstream mysvr {   
      server 127.0.0.1:7878;
      server 192.168.10.121:3333 backup;  #热备
    }
    error_page 404 https://www.baidu.com; #错误页
    server {
        keepalive_requests 120; #单连接请求上限次数。
        listen       4545;   #监听端口
        server_name  127.0.0.1;   #监听地址       
        location  ~*^.+$ {       #请求的url过滤,正则匹配,~为区分大小写,~*为不区分大小写。
           #root path;  #根目录
           #index vv.txt;  #设置默认页
           proxy_pass  http://mysvr;  #请求转向mysvr 定义的服务器列表
           deny 127.0.0.1;  #拒绝的ip
           allow 172.18.5.54; #允许的ip           
        } 
    }
} 

上面是nginx的基本配置,需要注意的有以下几点:

1、1.$remote_addr 与$http_x_forwarded_for 用以记录客户端的ip地址; 2.$remote_user :用来记录客户端用户名称; 3.$time_local : 用来记录访问时间与时区;4.$request : 用来记录请求的url与http协议;

  5.$status : 用来记录请求状态;成功是200, 6.$body_bytes_s ent :记录发送给客户端文件主体内容大小;7.$http_referer :用来记录从那个页面链接访问过来的; 8.$http_user_agent :记录客户端浏览器的相关信息;

2、惊群现象:一个网路连接到来,多个睡眠的进程被同事叫醒,但只有一个进程能获得链接,这样会影响系统性能。

3、每个指令必须有分号结束。

 

Nginx代理功能与负载均衡详解

 

序言

Nginx的代理功能与负载均衡功能是最常被用到的,关于nginx的基本语法常识与配置已在上篇文章中有说明,这篇就开门见山,先描述一些关于代理功能的配置,再说明负载均衡详细。

Nginx代理服务的配置说明

1、上一篇中我们在http模块中有下面的配置,当代理遇到状态码为404时,我们把404页面导向百度。

error_page 404 https://www.baidu.com; #错误页

然而这个配置,细心的朋友可以发现他并没有起作用。

如果我们想让他起作用,我们必须配合着下面的配置一起使用

proxy_intercept_errors on;    #如果被代理服务器返回的状态码为400或者大于400,设置的error_page配置起作用。默认为off。

2、如果我们的代理只允许接受get,post请求方法的一种

proxy_method get;    #支持客户端的请求方法。post/get;

3、设置支持的http协议版本

proxy_http_version 1.0 ; #Nginx服务器提供代理服务的http协议版本1.0,1.1,默认设置为1.0版本

4、如果你的nginx服务器给2台web服务器做代理,负载均衡算法采用轮询,那么当你的一台机器web程序iis关闭,也就是说web不能访问,那么nginx服务器分发请求还是会给这台不能访问的web服务器,如果这里的响应连接时间过长,就会导致客户端的页面一直在等待响应,对用户来说体验就打打折扣,这里我们怎么避免这样的情况发生呢。这里我配张图来说明下问题。

 

如果负载均衡中其中web2发生这样的情况,nginx首先会去web1请求,但是nginx在配置不当的情况下会继续分发请求道web2,然后等待web2响应,直到我们的响应时间超时,才会把请求重新分发给web1,这里的响应时间如果过长,用户等待的时间就会越长。

下面的配置是解决方案之一。

proxy_connect_timeout 1;   #nginx服务器与被代理的服务器建立连接的超时时间,默认60秒
proxy_read_timeout 1; #nginx服务器想被代理服务器组发出read请求后,等待响应的超时间,默认为60秒。
proxy_send_timeout 1; #nginx服务器想被代理服务器组发出write请求后,等待响应的超时间,默认为60秒。
proxy_ignore_client_abort on;  #客户端断网时,nginx服务器是否终端对被代理服务器的请求。默认为off。

5、如果使用upstream指令配置啦一组服务器作为被代理服务器,服务器中的访问算法遵循配置的负载均衡规则,同时可以使用该指令配置在发生哪些异常情况时,将请求顺次交由下一组服务器处理。

proxy_next_upstream timeout;  #反向代理upstream中设置的服务器组,出现故障时,被代理服务器返回的状态值。error|timeout|invalid_header|http_500|http_502|http_503|http_504|http_404|off

error:建立连接或向被代理的服务器发送请求或读取响应信息时服务器发生错误。

timeout:建立连接,想被代理服务器发送请求或读取响应信息时服务器发生超时。

invalid_header:被代理服务器返回的响应头异常。

off:无法将请求分发给被代理的服务器。

http_400,….:被代理服务器返回的状态码为400,500,502,等。

6、如果你想通过http获取客户的真是ip而不是获取代理服务器的ip地址,那么要做如下的设置。

proxy_set_header Host $host; #只要用户在浏览器中访问的域名绑定了 VIP VIP 下面有RS;则就用$host ;host是访问URL中的域名和端口  www.taobao.com:80
proxy_set_header X-Real-IP $remote_addr;  #把源IP 【$remote_addr,建立HTTP连接header里面的信息】赋值给X-Real-IP;这样在代码中 $X-Real-IP来获取 源IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;#在nginx 作为代理服务器时,设置的IP列表,会把经过的机器ip,代理机器ip都记录下来,用 【,】隔开;代码中用 echo $x-forwarded-for |awk -F, '{print $1}' 来作为源IP

关于X-Forwarded-For与X-Real-IP的一些相关文章我推荐一位博友的:HTTP 请求头中的 X-Forwarded-For ,这位博友对http协议有一系列的文章阐述,推荐大家去关注下。

7、下面是我的一个关于代理配置的配置文件部分,仅供参考。

    include       mime.types;   #文件扩展名与文件类型映射表
    default_type  application/octet-stream; #默认文件类型,默认为text/plain
    #access_log off; #取消服务日志    
    log_format myFormat ' $remote_addr–$remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for'; #自定义格式
    access_log log/access.log myFormat;  #combined为日志格式的默认值
    sendfile on;   #允许sendfile方式传输文件,默认为off,可以在http块,server块,location块。
    sendfile_max_chunk 100k;  #每个进程每次调用传输数量不能大于设定的值,默认为0,即不设上限。
    keepalive_timeout 65;  #连接超时时间,默认为75s,可以在http,server,location块。
    proxy_connect_timeout 1;   #nginx服务器与被代理的服务器建立连接的超时时间,默认60秒
    proxy_read_timeout 1; #nginx服务器想被代理服务器组发出read请求后,等待响应的超时间,默认为60秒。
    proxy_send_timeout 1; #nginx服务器想被代理服务器组发出write请求后,等待响应的超时间,默认为60秒。
    proxy_http_version 1.0 ; #Nginx服务器提供代理服务的http协议版本1.0,1.1,默认设置为1.0版本。
    #proxy_method get;    #支持客户端的请求方法。post/get;
    proxy_ignore_client_abort on;  #客户端断网时,nginx服务器是否终端对被代理服务器的请求。默认为off。
    proxy_ignore_headers "Expires" "Set-Cookie";  #Nginx服务器不处理设置的http相应投中的头域,这里空格隔开可以设置多个。
    proxy_intercept_errors on;    #如果被代理服务器返回的状态码为400或者大于400,设置的error_page配置起作用。默认为off。
    proxy_headers_hash_max_size 1024; #存放http报文头的哈希表容量上限,默认为512个字符。
    proxy_headers_hash_bucket_size 128; #nginx服务器申请存放http报文头的哈希表容量大小。默认为64个字符。
    proxy_next_upstream timeout;  #反向代理upstream中设置的服务器组,出现故障时,被代理服务器返回的状态值。error|timeout|invalid_header|http_500|http_502|http_503|http_504|http_404|off
    #proxy_ssl_session_reuse on; 默认为on,如果我们在错误日志中发现“SSL3_GET_FINSHED:digest check failed”的情况时,可以将该指令设置为off。

Nginx负载均衡详解

上一篇中我说啦nginx有哪些中负载均衡算法。这一结我就给如果操作配置的给大家做详细说明下。

首先给大家说下upstream这个配置的,这个配置是写一组被代理的服务器地址,然后配置负载均衡的算法。这里的被代理服务器地址有2中写法。

upstream mysvr { 
      server 192.168.10.121:3333;
      server 192.168.10.122:3333;
    }
 server {
        ....
        location  ~*^.+$ {         
           proxy_pass  http://mysvr;  #请求转向mysvr 定义的服务器列表         
        } 
upstream mysvr { 
      server  http://192.168.10.121:3333;
      server  http://192.168.10.122:3333;
    }
 server {
        ....
        location  ~*^.+$ {         
           proxy_pass  mysvr;  #请求转向mysvr 定义的服务器列表         
        } 

然后,就来点实战的东西。

1、热备:如果你有2台服务器,当一台服务器发生事故时,才启用第二台服务器给提供服务。服务器处理请求的顺序:AAAAAA突然A挂啦,BBBBBBBBBBBBBB…..

upstream mysvr { 
      server 127.0.0.1:7878; 
      server 192.168.10.121:3333 backup;  #热备     
    }

2、轮询:nginx默认就是轮询其权重都默认为1,服务器处理请求的顺序:ABABABABAB….

upstream mysvr { 
      server 127.0.0.1:7878;
      server 192.168.10.121:3333;       
    }

3、加权轮询:跟据配置的权重的大小而分发给不同服务器不同数量的请求。如果不设置,则默认为1。下面服务器的请求顺序为:ABBABBABBABBABB….

 upstream mysvr { 
      server 127.0.0.1:7878 weight=1;
      server 192.168.10.121:3333 weight=2;
}

4、ip_hash:nginx会让相同的客户端ip请求相同的服务器。

upstream mysvr { 
      server 127.0.0.1:7878; 
      server 192.168.10.121:3333;
      ip_hash;
    }

5、如果你对上面4种均衡算法不是很理解,那么麻烦您去看下我上一篇配的图片,可能会更加容易理解点。

到这里你是不是感觉nginx的负载均衡配置特别简单与强大,那么还没完,咱们继续哈,这里扯下蛋。

关于nginx负载均衡配置的几个状态参数讲解。

  • down,表示当前的server暂时不参与负载均衡。

  • backup,预留的备份机器。当其他所有的非backup机器出现故障或者忙的时候,才会请求backup机器,因此这台机器的压力最轻。

  • max_fails,允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误。

  • fail_timeout,在经历了max_fails次失败后,暂停服务的时间。max_fails可以和fail_timeout一起使用。

 upstream mysvr { 
      server 127.0.0.1:7878 weight=2 max_fails=2 fail_timeout=2;
      server 192.168.10.121:3333 weight=1 max_fails=2 fail_timeout=1;    
    }

到这里应该可以说nginx的内置负载均衡算法已经没有货啦。如果你像跟多更深入的了解nginx的负载均衡算法,nginx官方提供一些插件大家可以了解下。

jvm CPU飚高 查询java线程

1,根据top命令,找到占用CPU高的进程的PID,比如2633。

2,找出该进程内最耗费CPU的线程,可以使用

1)ps -Lfp pid

2)ps -mp pid -o THREAD, tid, time

3)top -Hp pid

这里用第三个,输出如下:

TIME列就是各个Java线程耗费的CPU时间,CPU时间最长的是线程ID为21742的线程,用

printf "%x\n" 21742

得到21742的十六进制值为54ee,下面会用到。

3. 下一步轮到jstack上场了,它用来输出进程21711的堆栈信息,然后根据线程ID的十六进制值grep,如下:

jstack 2633 |grep 54ee -A 30
"PollIntervalRetrySchedulerThread" prio=10 tid=0x00007f950043e000 nid=0x54ee in Object.wait()

可以看到CPU消耗在PollIntervalRetrySchedulerThread这个类的Object.wait(),我找了下我的代码,定位到下面的代码:

// Idle wait
getLog().info("Thread [" + getName() + "] is idle waiting..."); schedulerThreadState = PollTaskSchedulerThreadState.IdleWaiting; long now = System.currentTimeMillis(); long waitTime = now + getIdleWaitTime(); long timeUntilContinue = waitTime - now; synchronized(sigLock) {  try {   if(!halted.get()) {    sigLock.wait(timeUntilContinue);   }  }  catch (InterruptedException ignore) {  } }

它是轮询任务的空闲等待代码,上面的sigLock.wait(timeUntilContinue)就对应了前面的Object.wait()。

Springboot配置使用ssl,Nginx配置https

SSL(Secure Sockets Layer 安全套接层)是为网络通信提供安全及数据完整性的一种安全协议,SSL在网络传输层对网络连接进行加密,SSL协议位于TCP/IP协议与各种应用层协议之间,为数据通信提供安全支持。SSL协议分为两层,SSL记录协议建立在TCP之上,为高层协议提供数据封装、压缩、加密等基本功能支持。SSL握手协议建立在SSL记录协议之上,用户实际数据传输开始前进行身份验证、协商加密算法、交换加密秘钥。

1.生成证书,可以使自签名或者从SSL证书授权中心获得的。

JDK中keytool是一个证书管理工具,可以生成自签名证书。 
本人这里用的系统是deepin,然后生成命令如下(找不到keytoo命令的先去配置java环境) 
我指定的名字叫tomcat.keystore 别名叫tomcat,密码自己设置,我这里用的tomcat,最后那个直接按得回车

keytool -genkey -alias tomcat -keyalg RSA -keystore /home/gzr/tomcat.keystore

2.SpringBoot配置SSL

1. 将这个tomcat.keystore拷贝到项目资源目录resources下

2. 然后配置application.yml

server:
  port: 8443
  session:
    timeout: 3000
  ssl:
    key-store: classpath:tomcat.keystore
    key-store-password: 123456
    key-store-type: PKCS12
    key-alias: tomcat

此刻启动项目,输入 https://localhost:8443/即可

3.Http自动跳转到Https

看下实现吧,在运行主类里面,加入如下代码

package com.caul;

import org.apache.catalina.Context;
import org.apache.catalina.connector.Connector;
import org.apache.tomcat.util.descriptor.web.SecurityCollection;
import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class SpringbootmyApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootmyApplication.class, args);
    }

    /**
     * it's for set http url auto change to https
     */
    @Bean
    public EmbeddedServletContainerFactory servletContainer(){
        TomcatEmbeddedServletContainerFactory tomcat=new TomcatEmbeddedServletContainerFactory(){
            @Override
            protected void postProcessContext(Context context) {
                SecurityConstraint securityConstraint=new SecurityConstraint();
                securityConstraint.setUserConstraint("CONFIDENTIAL");//confidential
                SecurityCollection collection=new SecurityCollection();
                collection.addPattern("/*");
                securityConstraint.addCollection(collection);
                context.addConstraint(securityConstraint);
            }
        };
        tomcat.addAdditionalTomcatConnectors(httpConnector());
        return tomcat;
    }

    @Bean
    public Connector httpConnector(){
        Connector connector=new Connector("org.apache.coyote.http11.Http11NioProtocol");
        connector.setScheme("http");
        connector.setPort(8080);
        connector.setSecure(false);
        connector.setRedirectPort(8443);
        return connector;
    }

}

此时运行http://localhost:8080,会自动跳转到https://localhost:8443

4.Nginx的配置

  • 先签发证书
############ 证书颁发机构
# CA机构私钥
openssl genrsa -out ca.key 2048
# CA证书
openssl req -x509 -new -key ca.key -out ca.crt
############ 服务端
# 生成服务端私钥
openssl genrsa -out server.key 2048
# 生成服务端证书请求文件
openssl req -new -key server.key -out server.csr
# 使用CA证书生成服务端证书  关于sha256,默认使用的是sha1,在新版本的chrome中会被认为是不安全的,因为使用了过时的加密算法。
openssl x509 -req -sha256 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650 -out server.crt    
# 打包服务端的资料为pkcs12格式(非必要,只是换一种格式存储上一步生成的证书) 生成过程中,需要创建访问密码,请记录下来。
openssl pkcs12 -export -in server.crt -inkey server.key -out server.pkcs12

新建任意名的配置文件在/etc/nginx/conf.d/下

upstream test {
  server 127.0.0.1:8443;
}

server {
  listen 443;
  server_name wx.baidu.com;
  ssl on;
  ssl_certificate  /home/er/https/server.crt;
  ssl_certificate_key  /home/er/https/server.key;

  location / {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-Nginx-Proxt true;

    proxy_pass https://test;
    proxy_redirect off;
  }
}

重启nginx即可:

sudo nginx -s reload

window指令集合

1. 查看端口占用情况

netstat [option]|grep 过滤条件
例子: netstat -ano|findstr 8000 查询8000端口访问的程序
根据端口,找到PID
for /f "tokens=5" %i in ('netstat -ano^|findstr 8000') do @echo %i

2. 查看进程

tasklist [option]|grep 过滤条件
例子:
tasklist |findstr tocmate
查询详情
tasklist /V|findstr tocmat
根据进程名称,找到PID
for /f "tokens=2" %i in ('tasklist^|findstr java') do @echo %i

TASKLIST [/S system [/U username [/P [password]]]]
[/M [module] | /SVC | /V] [/FI filter] [/FO format] [/NH]

描述:
该工具显示在本地或远程机器上当前运行的进程列表。


参数列表:
/S system 指定连接到的远程系统。

/U [domain\]user 指定应该在哪个用户上下文执行这个命令。

/P [password] 为提供的用户上下文指定密码。如果省略,则
提示输入。

/M [module] 列出当前使用所给 exe/dll 名称的所有任务。
如果没有指定模块名称,显示所有加载的模块。

/SVC 显示每个进程中主持的服务。

/APPS 显示应用商店应用及其关联的进程。

/V 显示详细任务信息。

/FI filter 显示一系列符合筛选器
指定条件的任务。

/FO format 指定输出格式。
有效值: “TABLE”、”LIST”、”CSV”。

/NH 指定列标题不应该
在输出中显示。
只对 “TABLE” 和 “CSV” 格式有效。

/? 显示此帮助消息。

6.杀死进程

taskkill /F /PID 进程号
例子: taskkill /F /PID 2023

TASKKILL [/S system [/U username [/P [password]]]]
{ [/FI filter] [/PID processid | /IM imagename] } [/T] [/F]

描述:
使用该工具按照进程 ID (PID) 或映像名称终止任务。

参数列表:
/S system 指定要连接的远程系统。

/U [domain\]user 指定应该在哪个用户上下文执行这个命令。

/P [password] 为提供的用户上下文指定密码。如果忽略,提示
输入。

/FI filter 应用筛选器以选择一组任务。
允许使用 “*”。例如,映像名称 eq acme*

/PID processid 指定要终止的进程的 PID。
使用 TaskList 取得 PID。

/IM imagename 指定要终止的进程的映像名称。通配符 ‘*’可用来
指定所有任务或映像名称。

/T 终止指定的进程和由它启用的子进程。

/F 指定强制终止进程。

/? 显示帮助消息。

筛选器:
筛选器名 有效运算符 有效值
———– ————— ————————-
STATUS eq, ne RUNNING |
NOT RESPONDING | UNKNOWN
IMAGENAME eq, ne 映像名称
PID eq, ne, gt, lt, ge, le PID 值
SESSION eq, ne, gt, lt, ge, le 会话编号。
CPUTIME eq, ne, gt, lt, ge, le CPU 时间,格式为
hh:mm:ss。
hh – 时,
mm – 分,ss – 秒
MEMUSAGE eq, ne, gt, lt, ge, le 内存使用量,单位为 KB
USERNAME eq, ne 用户名,格式为 [domain\]user
MODULES eq, ne DLL 名称
SERVICES eq, ne 服务名称
WINDOWTITLE eq, ne 窗口标题

说明
—-
1) 只有在应用筛选器的情况下,/IM 切换才能使用通配符 ‘*’。
2) 远程进程总是要强行 (/F) 终止。
3) 当指定远程机器时,不支持 “WINDOWTITLE” 和 “STATUS” 筛选器。

例如:
TASKKILL /IM notepad.exe
TASKKILL /PID 1230 /PID 1241 /PID 1253 /T
TASKKILL /F /IM cmd.exe /T
TASKKILL /F /FI “PID ge 1000” /FI “WINDOWTITLE ne untitle*”
TASKKILL /F /FI “USERNAME eq NT AUTHORITY\SYSTEM” /IM notepad.exe
TASKKILL /S system /U 域\用户名 /FI “用户名 ne NT*” /IM *
TASKKILL /S system /U username /P password /FI “IMAGENAME eq note*”

 

7. 拷贝

copy [option] from to
例子: copy /-Y aaa/* /bbb 把aaa目录以及子目录和文件属性也传递到了/bbb


COPY [/D] [/V] [/N] [/Y | /-Y] [/Z] [/L] [/A | /B ] source [/A | /B]
[+ source [/A | /B] [+ …]] [destination [/A | /B]]

source 指定要复制的文件。
/A 表示一个 ASCII 文本文件。
/B 表示一个二进位文件。
/D 允许解密要创建的目标文件
destination 为新文件指定目录和/或文件名。
/V 验证新文件写入是否正确。
/N 复制带有非 8dot3 名称的文件时,
尽可能使用短文件名。
/Y 不使用确认是否要覆盖现有目标文件
的提示。
/-Y 使用确认是否要覆盖现有目标文件
的提示。
/Z 用可重新启动模式复制已联网的文件。
/L 如果源是符号链接,请将链接复制
到目标而不是源链接指向的实际文件。

8. 移动

move [option] from to
例子: move /Y aaa/* /bbb 把aaa目录以及子目录和文件属性也传递到了/bbb

TASKLIST [/S system [/U username [/P [password]]]]
[/M [module] | /SVC | /V] [/FI filter] [/FO format] [/NH]

描述:
该工具显示在本地或远程机器上当前运行的进程列表。


参数列表:
/S system 指定连接到的远程系统。

/U [domain\]user 指定应该在哪个用户上下文执行这个命令。

/P [password] 为提供的用户上下文指定密码。如果省略,则
提示输入。

/M [module] 列出当前使用所给 exe/dll 名称的所有任务。
如果没有指定模块名称,显示所有加载的模块。

/SVC 显示每个进程中主持的服务。

/APPS 显示应用商店应用及其关联的进程。

/V 显示详细任务信息。

/FI filter 显示一系列符合筛选器
指定条件的任务。

/FO format 指定输出格式。
有效值: “TABLE”、”LIST”、”CSV”。

/NH 指定列标题不应该
在输出中显示。
只对 “TABLE” 和 “CSV” 格式有效。

/? 显示此帮助消息。

9. 后台执行命令

start /b command >日志输出
例子:start /b ./bin/startup.cmd >nohup.out

 

 

 

maven自动打包命令(windows环境)

echo off

set version=1.0.0
set env=simulation
set base_path=E:\project\demo
set dest_path=E:\deploy\demo

echo 基础包install 开始

SET lenInstall=3

SET pkgLib[0]=lib1
SET pkgLib[1]=lib2
SET pkgLib[2]=lib3

SET idx=0

:LoopLib
IF %idx% EQU %lenInstall% GOTO StartSrv

FOR /F "usebackq delims==. tokens=1-2" %%I IN (`SET pkgLib[%idx%]`) DO (
cd /d %base_path%\%%J
cmd /k "mvn clean install -Dmaven.test.skip=true&&exit"
echo %%J finished
)

SET /A idx=%idx% + 1

GOTO LoopLib

:StartSrv
echo 基础包install 完成


echo 服务包package 开始

SET lenPkg=3

SET pkgSrv[0]=service1
SET pkgSrv[1]=service2
SET pkgSrv[2]=service3

SET idx=0

:LoopSrv
IF %idx% EQU %lenPkg% GOTO Finished

FOR /F "usebackq delims==. tokens=1-2" %%I IN (`SET pkgSrv[%idx%]`) DO (
cd /d %base_path%\%%J
cmd /k "mvn clean package -Dmaven.test.skip=true -P%env%&&exit"
cd target
cp *%version%.* %dest_path%\
ECHO %%J finished
)

SET /A idx=%idx% + 1

GOTO LoopSrv

:Finished
echo 服务包package 完成

 

echo on

pause