Jersey 方法拦截器

如果我们需要控制用户对接口的访问,例如登陆控制,权限控制等,就需要使用方法拦截器。
    由于Jersey中的AOP是基于HK2框架实现的,所以对应的拦截器的功能也是由HK2框架实现。
    现在我们模拟实现一个登陆拦截器的功能。
3.1 创建自定义注解
  1. @Documented
  2. @Target({ElementType.METHOD, ElementType.TYPE})
  3. @Retention(RetentionPolicy.RUNTIME)
  4. public @interface LoginTest {
  5. }
 
3.2 方法拦截器
  1. @LoginTest
  2. public class LoginTestMethodInterceptor implements MethodInterceptor {
  3. @Override
  4. public Object invoke(MethodInvocation methodInvocation) throws Throwable {
  5. return "没有权限访问";
  6. }
  7. }
    
3.3 方法拦截器的绑定
    Jersey在调用方法拦截器的时候,需要InterceptionService的实现。
   该接口中有三个方法,在执行对应的接口方法之前会调用getMethodInteceptors()方法,获取对应的拦截器,并执行拦截器。
public class JerseyInterceptor implements InterceptionService {
private static Map<Annotation, MethodInterceptor> map = new HashMap<>();
static{
Annotation[] annotations = LoginTestMethodInterceptor.class.getAnnotations();
for(Annotation annotation : annotations){
map.put(annotation, new LoginTestMethodInterceptor());
}
}
@Override
public Filter getDescriptorFilter() {
return new Filter() {
public boolean matches(Descriptor descriptor) {
return true;
}
};
}
@Override
public List<MethodInterceptor> getMethodInterceptors(Method method) {
Annotation[] annotations = method.getAnnotations();
List<MethodInterceptor> list = new ArrayList<>();
for (Annotation annotation :annotations){
if(map.get(annotation) != null){
list.add(map.get(annotation));
}
}
return list;
}
@Override
public List<ConstructorInterceptor> getConstructorInterceptors(Constructor<?> constructor) {
return null;
}
}
上面代码可以看到,我们是将注解与拦截器绑定,通过方法上的注解,获取方法对应的拦截器,并执行拦截器。 我们创建的拦截服务实现,需要与拦截服务进行绑定,这时需要AbstracctBinding对象的实现‘。
public class JerseyBinding extends AbstractBinder {
@Override
protected void configure() {
this.bind(JerseyInterceptor.class).to(InterceptionService.class).in(Singleton.class);
}
}

为了使绑定生效,我们需要定义特征类,用于注册该绑定

 
  1. public class JerseyFeature implements Feature {
  2. @Override
  3. public boolean configure(FeatureContext context) {
  4. context.register(new JerseyBinding());
  5. return true;
  6. }
  7. }
同样我们需要在ResourceConfig中注册该特征类
  1. register(JerseyFeature.class);
3,4 测试
    测试接口如下
 
  1. @Path("/test")
  2. public class TestResource {
  3. @Path("/1")
  4. @GET
  5. public String test1(){
  6. return "不带拦截器";
  7. }
  8. @Path("/2")
  9. @GET
  10. @LoginTest
  11. public String test2(){
  12. return "不带拦截器";
  13. }
  14. }
我们访问test/1的时候可以看到不带拦截器,访问test/2的时候可以看到没有访问权限

Jersey 请求/响应拦截器

拦截器主要用来操作实体,操作是通过实体输入输出流来完成。例如对请求实体进行编码。有两种拦截器,ReaderInterceptor 与WriterInterceptor。 Reader拦截器用来操作输入实体流(inbound entity streams)。所以,使用reader拦截器,你可以在服务器端操作请求实体流,在客户端操作响应实体流。(这个实体是从server response读取)。Writer 拦截器,writer 拦截器用于将实体写入”wire”中。在服务端这表示,写出响应实体。在客户端表示为发送到服务器端的请求写请求实体。Writer 与 Reader拦截器 在  消息 readers或writers被执行前执行,其目的是包装将被用在消息reader与writer中的实体流。

下面演示writer拦截器,对整个实体进行GZIP压缩。

[java]  view plain  copy
  1. public class GZIPWriterInterceptor implements WriterInterceptor {  
  2.    
  3.     @Override  
  4.     public void aroundWriteTo(WriterInterceptorContext context)  
  5.                     throws IOException, WebApplicationException {  
  6.         final OutputStream outputStream = context.getOutputStream();  
  7.         context.setOutputStream(new GZIPOutputStream(outputStream));  
  8.         context.proceed();  
  9.     }  
  10. }  

GZIPReaderInterceptor通过GZIPInputStream包装原始的输入流。此后对实体流的读取或得到压缩后的流。aroundReadFrom拦截方法必须返回一个实体。实体是从ReaderInterceptorContext的proceed方法中返回。Proceed方法在内部调用包装的拦截器,这个拦截器必须返回一个实体。被在调用链中的上一个拦截器调用的proceed方法会将用message bodyreader,该方法会反序列化实体,并返回结果。如果需要,每次拦截器都能改变实体,但在大多数的情况下,拦截器仅返回从proceed方法中返回的实体。

上文已经提交,拦截器用来操作实体。与WriterInterceptorContext暴漏的方法类似,ReaderInterceptorContext也引入一些用来修改请求或响应属性的方法。例如,HTTP 头,URIs,以及HTTP 方法。

 与过滤器类似, 拦截器也可以通过命名注解的方式进行绑定, 或者实现DynamicFeature的方式进行动态绑定.

10.5 命名绑定

过滤器与拦截器可以指定名称。绑定后拦截器或过滤器仅仅对特殊的特定的资源方法执行。如果没有进行命名保定,那么过滤器或拦截器被称为全局过滤器或拦截器。

可以使用@NameBinding注解,将过滤器或拦截器可以被分配给一个资源方法。这个注解以元注解的形式使用,可以注解其它注解。例子如下:

[java]  view plain  copy
  1. …  
  2. import java.lang.annotation.Retention;  
  3. import java.lang.annotation.RetentionPolicy;  
  4. import java.util.zip.GZIPInputStream;  
  5.    
  6. import javax.ws.rs.GET;  
  7. import javax.ws.rs.NameBinding;  
  8. import javax.ws.rs.Path;  
  9. import javax.ws.rs.Produces;  
  10. …  
  11.    
  12.    
  13. // 声明注解 
  14. //@Compress annotation is the name binding annotation  
  15. @NameBinding  
  16. @Retention(RetentionPolicy.RUNTIME)  
  17. public @interface Compress {}  
  18.    
  19.    
  20. //将注解和业务方法绑定
  21. @Path(“helloworld”)  
  22. public class HelloWorldResource {  
  23.    
  24.     @GET  
  25.     @Produces(“text/plain”)  
  26.     public String getHello() {  
  27.         return “Hello World!”;  
  28.     }  
  29.    
  30.     @GET  
  31.     @Path(“too-much-data”)  
  32.     @Compress  
  33.     public String getVeryLongString() {  
  34.         String str = … // very long string  
  35.         return str;  
  36.     }  
  37. }  
  38.    
  1. // 将注解和拦截器实现类绑定
  2. // interceptor will be executed only when resource methods  
  3. // annotated with @Compress annotation will be executed  
  4. @Compress  
  5. public class GZIPWriterInterceptor implements WriterInterceptor {  
  6.     @Override  
  7.     public void aroundWriteTo(WriterInterceptorContext context)  
  8.                     throws IOException, WebApplicationException {  
  9.         final OutputStream outputStream = context.getOutputStream();  
  10.         context.setOutputStream(new GZIPOutputStream(outputStream));  
  11.         context.proceed();  
  12.     }  
  13. }  

上述代码定义了注解@Compress,并用在方法getVeryLongString()上,以及GZIPWriterInterceptor拦截器上。拦截器仅在被注解的方法执行时才执行。应用程序中可以有多个命名绑定注解。当provider(拦截器与过滤器)通过命名注解注解后,它仅仅在标注有对应注解的方法被执行后才执行。

10.6 动态绑定

动态绑定是一种以动态的方法将拦截器与过滤器与处理方法关联的方式。10.5中的绑定使用了静态方法,当改变绑定时,需要重新编译代码。通过动态绑定,你可以在程序初始化时实现绑定的代码。

[java]  view plain  copy
  1. …  
  2. import javax.ws.rs.core.FeatureContext;  
  3. import javax.ws.rs.container.DynamicFeature;  
  4. …  
  5.    
  6. @Path(“helloworld”)  
  7. public class HelloWorldResource {  
  8.    
  9.     @GET  
  10.     @Produces(“text/plain”)  
  11.     public String getHello() {  
  12.         return “Hello World!”;  
  13.     }  
  14.    
  15.     @GET  
  16.     @Path(“too-much-data”)  
  17.     public String getVeryLongString() {  
  18.         String str = … // very long string  
  19.         return str;  
  20.     }  
  21. }  
  22.    
  23. // This dynamic binding provider registers GZIPWriterInterceptor  
  24. // only for HelloWorldResource and methods that contain  
  25. // “VeryLongString” in their name. It will be executed during  
  26. // application initialization phase.  
  27. public class CompressionDynamicBinding implements DynamicFeature {  
  28.    
  29.     @Override  
  30.     public void configure(ResourceInfo resourceInfo, FeatureContext context) {  
  31.         if (HelloWorldResource.class.equals(resourceInfo.getResourceClass())  
  32.                 && resourceInfo.getResourceMethod()  
  33.                     .getName().contains(“VeryLongString”)) {  
  34.             context.register(GZIPWriterInterceptor.class);  
  35.         }  
  36.     }  
  37. }  

10.4 过滤器拦截器的执行顺序

接下来看一下过滤器与拦截器的执行上下文。下面的步骤描述了JAX-RS客户端发出POS请求到服务器端。服务器接收到实体,并返回响应。GZIP reader与writer拦截器注册在客户端与服务器端。过滤器也注册在服务器端与客户端,并用来修改请求、响应头。

1.      客户端请求调用: 在客户端发起POST请求。

2.      ClientRequestFilters: 客户端请求过滤器执行,修改请求头。

3.      Client WriterInterceptor:在客户端注册的writer interceptor在MessageBodyWriter执行前执行。它通过GZipOutputStream对实体输出流进行封装。

4.      Client MessageBody writer: 客户端的message body writer被执行,它将实体写入写的GZipOutput流中。这个流将数据压缩,并将数据发送到”wire”中。

5.      Server:服务器收到请求。收到的数据实体是压缩过的数据,如果直接读,则读取的是压缩的数据。

6.      Server pre-matching ContainerRequestFilters: ContainerRequestFilters执行,并可以修改请求,来匹配不同的处理方法。

7.      Server: matching: 资源方法匹配完成。(根据请求找到请求处理方法)

8.      Server: post-matching ContainerRequestFilters:ContainerRequestFilters post matching filters被执行。这包括所有全局filters(没有命名绑定)的执行及绑定名称的filters的执行。

9.      Server ReaderInterceptor:reader 拦截器在服务器端执行,GZIPReaderInterceptor对输入流进行包装,转换为GZipInputStream并将其添加到上下文中。

10.  Server MessageBodyReader: server message body reader 被执行,并通过GZipInputStream对实体数据解压缩。这表示,reader将读取解压缩后的数据。

11.  服务器端资源方法被执行:反序列化的实习对象以参数的形式传递给资源方法。方法以response实体的形式返回这个实体。

12.  Server ContainerResponseFilters被执行,响应过滤器在服务器端被执行,并将response headers修改。

13.  Server WriterInterceptor 在服务器端被执行,并通过GZIPOuptutStream对原始输出流进行包装。

14.  Server MessageBodyWriter:message body writer在服务器端被执行,并将实体序列化,写入GZIPOutputStream中。GZIPOutputStream会将数据压缩,随后压缩的数据被发送到客户端。

15.  客户端接收到响应:响应包含压缩的实体数据。

16.  Client ClientResponseFilters:客户端相应过滤器被执行,并且修改响应头。

17.  客户端响应返回。the javax.ws.rs.core.Response从请求调用中返回。

18.  客户端代码调用response.readEntity():从响应中提取出实体部分。

19.  Client ReaderInterceptor:客户端reader 拦截器在readEntity被调用时执行。拦截器通过GZIPInputStream对实体输入流封装。

20.  Client MessageBodyReaders:客户端消息体reader被调用,并从GZIPInputStream中读取解压缩后的数据,并将这些数据反序列化。

21.  客户端:方法readEntity()返回实体。

需要注意的是在上述的场景中,reader与writer拦截器仅仅当实体存在时才会被调用。(当没有实体流要被写时,封装实体流没有意义)。

message body reader有同样的行为。拦截器在message body reader/writer之前执行,在实体被读或写之前拦截器可以对实体进行包装。

当拦截器并没有在messagebodyreader/writers执行前执行,将会出现异常。当对使用内部缓冲区的客户端response的实体读取多次,数据仅仅会被拦截一次,然后解码后的数据被存储于缓冲区中。

10.7 优先级

如果有多个拦截器或过滤器,那么可以通过优先级指定执行的顺序。通过注解@Priority可以定义优先级。注解接受一个整数作为优先级。过滤器与拦截器执行顺序是按优先级(升序)顺序执行。因此@Priority(1000)或在@Priority(2000)之前执行。而优先级用在响应处理时候,顺序正好相反。@Priority(2000)将在@Priority(1000)之前执行。

[java]  view plain  copy
  1. …  
  2. import javax.annotation.Priority;  
  3. import javax.ws.rs.Priorities;  
  4. …  
  5.    
  6. @Priority(2000)  
  7. public class ResponseFilter implements ContainerResponseFilter {  
  8.    
  9.     @Override  
  10.     public void filter(ContainerRequestContext requestContext,  
  11.                     ContainerResponseContext responseContext)  
  12.                     throws IOException {  
  13.    
  14.         responseContext.getHeaders().add(“X-Powered-By”“Jersey :-)”);  
  15.     }  
  16. }  

JDK内置工具使用-jstack命令(Java Stack Trace)

1、介绍

jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项”-J-d64″,Windows的jstack使用方式只支持以下的这种方式:

jstack [-l] pid

如果java程序崩溃生成core文件,jstack工具可以用来获得core文件的java stack和native stack的信息,从而可以轻松地知道java程序是如何崩溃和在程序何处发生问题。另外,jstack工具还可以附属到正在运行的java程序中,看到当时运行的java程序的java stack和native stack的信息, 如果现在运行的java程序呈现hung的状态,jstack是非常有用的。

2、命令格式
jstack [ option ] pid
jstack [ option ] executable core
jstack [ option ] [server-id@]remote-hostname-or-IP

3、常用参数说明

1)、options: 

executable Java executable from which the core dump was produced.

(可能是产生core dump的java可执行程序)

core 将被打印信息的core dump文件

remote-hostname-or-IP 远程debug服务的主机名或ip

server-id 唯一id,假如一台主机上多个远程debug服务 

2)、基本参数:

-F当’jstack [-l] pid’没有相应的时候强制打印栈信息

-l长列表. 打印关于锁的附加信息,例如属于java.util.concurrent的ownable synchronizers列表.

-m打印java和native c/c++框架的所有栈信息.

-h | -help打印帮助信息

pid 需要被打印配置信息的java进程id,可以用jps查询.

4、使用示例

转自:csdn-jstack命令

JDK内置工具使用-jmap命令(Java Memory Map)

1、介绍

打印出某个java进程(使用pid)内存内的,所有‘对象’的情况(如:产生那些对象,及其数量)。

可以输出所有内存中对象的工具,甚至可以将VM 中的heap,以二进制输出成文本。使用方法 jmap -histo pid。如果连用SHELL jmap -histo pid>a.log可以将其保存到文本中去,在一段时间后,使用文本对比工具,可以对比出GC回收了哪些对象。jmap -dump:format=b,file=outfile 3024可以将3024进程的内存heap输出出来到outfile文件里,再配合MAT(内存分析工具(Memory Analysis Tool),使用参见:http://blog.csdn.net/fenglibing/archive/2011/04/02/6298326.aspx)或与jhat (Java Heap Analysis Tool)一起使用,能够以图像的形式直观的展示当前内存是否有问题。

64位机上使用需要使用如下方式:

jmap -J-d64 -heap pid

2、命令格式

SYNOPSIS

       jmap [ option ] pid

       jmap [ option ] executable core

       jmap [ option ] [server-id@]remote-hostname-or-IP

3、参数说明

1)、options: 

executable Java executable from which the core dump was produced.

(可能是产生core dump的java可执行程序)

core 将被打印信息的core dump文件

remote-hostname-or-IP 远程debug服务的主机名或ip

server-id 唯一id,假如一台主机上多个远程debug服务 

2)、基本参数:

-dump:[live,]format=b,file= 使用hprof二进制形式,输出jvm的heap内容到文件=. live子选项是可选的,假如指定live选项,那么只输出活的对象到文件. 

-finalizerinfo 打印正等候回收的对象的信息.

-heap 打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用情况.

-histo[:live] 打印每个class的实例数目,内存占用,类全名信息. VM的内部类名字开头会加上前缀”*”. 如果live子参数加上后,只统计活的对象数量. 

-permstat 打印classload和jvm heap长久层的信息. 包含每个classloader的名字,活泼性,地址,父classloader和加载的class数量. 另外,内部String的数量和占用内存数也会打印出来. 

-F 强迫.在pid没有相应的时候使用-dump或者-histo参数. 在这个模式下,live子参数无效. 

-h | -help 打印辅助信息 

-J 传递参数给jmap启动的jvm. 

pid 需要被打印配相信息的java进程id,创业与打工的区别 – 博文预览,可以用jps查问.

4、使用示例

1)、[fenglb@ccbu-156-5 ~]$ jmap -histo 4939

[输出较多这里不贴了]

2)、[fenglb@ccbu-156-5 ~]$ jmap -dump:format=b,file=test.bin 4939

Dumping heap to /home/fenglb/test.bin …

Heap dump file created

转自:CSDN-jmap命令(Java Memory Map)

JVM内置工具-jstat命令(Java Virtual Machine Statistics Monitoring Tool)

1、介绍

Jstat用于监控基于HotSpot的JVM,对其堆的使用情况进行实时的命令行的统计,使用jstat我们可以对指定的JVM做如下监控:

– 类的加载及卸载情况

– 查看新生代、老生代及持久代的容量及使用情况

– 查看新生代、老生代及持久代的垃圾收集情况,包括垃圾回收的次数及垃圾回收所占用的时间

– 查看新生代中Eden区及Survior区中容量及分配情况等

jstat工具特别强大,它有众多的可选项,通过提供多种不同的监控维度,使我们可以从不同的维度来了解到当前JVM堆的使用情况。详细查看堆内各个部分的使用量,使用的时候必须加上待统计的Java进程号,可选的不同维度参数以及可选的统计频率参数。

它主要是用来显示GC及PermGen相关的信息,如果对GC不怎么了解,先看这篇文章:http://blog.csdn.net/fenglibing/archive/2011/04/13/6321453.aspx,否则其中即使你会使用jstat这个命令,你也看不懂它的输出。

 2、语法

     jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ]

    generalOption – 单个的常用的命令行选项,如-help, -options, 或 -version。

    outputOptions –一个或多个输出选项,由单个的statOption选项组成,可以和-t, -h, and -J等选项配合使用。

    statOption

    根据jstat统计的维度不同,可以使用如下表中的选项进行不同维度的统计,不同的操作系统支持的选项可能会不一样,可以通过-options选项,查看不同操作系统所支持选项,如:

OptionDisplays…
class用于查看类加载情况的统计
compiler用于查看HotSpot中即时编译器编译情况的统计
gc用于查看JVM中堆的垃圾收集情况的统计
gccapacity用于查看新生代、老生代及持久代的存储容量情况
gccause用于查看垃圾收集的统计情况(这个和-gcutil选项一样),如果有发生垃圾收集,它还会显示最后一次及当前正在发生垃圾收集的原因。
gcnew用于查看新生代垃圾收集的情况
gcnewcapacity用于查看新生代的存储容量情况
gcold用于查看老生代及持久代发生GC的情况
gcoldcapacity用于查看老生代的容量
gcpermcapacity用于查看持久代的容量
gcutil用于查看新生代、老生代及持代垃圾收集的情况
printcompilationHotSpot编译方法的统计

    -h n

        用于指定每隔几行就输出列头,如果不指定,默认是只在第一行出现列头。

    -JjavaOption

        用于将给定的javaOption传给java应用程序加载器,例如,“-J-Xms48m”将把启动内存设置为48M。如果想查看可以传递哪些选项到应用程序加载器中,可以相看如下的文档:

        Linux and Solaris:http://docs.oracle.com/javase/1.5.0/docs/tooldocs/solaris/java.html

        Windows: http://docs.oracle.com/javase/1.5.0/docs/tooldocs/windows/java.html

    -t n

        用于在输出内容的第一列显示时间戳,这个时间戳代表的时JVM开始启动到现在的时间(注:在IBM JDK5中是没有这个选项的)。

    vmid  – VM的进程号,即当前运行的java进程号。

    还有两个关于显示频率的选项:

    interval–间隔时间,单位可以是秒或者毫秒,通过指定s或ms确定,默认单位为毫秒。

    count-打印次数,如果缺省则打印无数次。

3、不同的统计维度(statOption)及输出说明

    -class

列名说明
Loaded加载了的类的数量
Bytes加载了的类的大小,单为Kb
Unloaded卸载了的类的数量
Bytes卸载了的类的大小,单为Kb
Time花在类的加载及卸载的时间

     -compiler

列名说明
Compiled编译任务执行的次数
Failed编译任务执行失败的次数
Invalid编译任务非法执行的次数
Time执行编译花费的时间
FailedType最后一次编译失败的编译类型
FailedMethod最后一次编译失败的类名及方法名

     -gc

列名说明
S0C新生代中Survivor space中S0当前容量的大小(KB)
S1C新生代中Survivor space中S1当前容量的大小(KB)
S0U新生代中Survivor space中S0容量使用的大小(KB)
S1U新生代中Survivor space中S1容量使用的大小(KB)
ECEden space当前容量的大小(KB)
EUEden space容量使用的大小(KB)
OCOld space当前容量的大小(KB)
OUOld space使用容量的大小(KB)
PCPermanent space当前容量的大小(KB)
PUPermanent space使用容量的大小(KB)
YGC从应用程序启动到采样时发生 Young GC 的次数
YGCT从应用程序启动到采样时 Young GC 所用的时间(秒)
FGC从应用程序启动到采样时发生 Full GC 的次数
FGCT从应用程序启动到采样时 Full GC 所用的时间(秒)
GCTT从应用程序启动到采样时用于垃圾回收的总时间(单位秒),它的值等于YGC+FGC

    -gccapacity

列名说明
NGCMN新生代的最小容量大小(KB)
NGCMX新生代的最大容量大小(KB)
NGC当前新生代的容量大小(KB)
S0C当前新生代中survivor space 0的容量大小(KB)
S1C当前新生代中survivor space 1的容量大小(KB)
ECEden space当前容量的大小(KB)
OGCMN老生代的最小容量大小(KB)
OGCMX老生代的最大容量大小(KB)
OGC当前老生代的容量大小(KB)
OC当前老生代的空间容量大小(KB)
PGCMN持久代的最小容量大小(KB)
PGCMX持久代的最大容量大小(KB)
PGC当前持久代的容量大小(KB)
PC当前持久代的空间容量大小(KB)
YGC从应用程序启动到采样时发生 Young GC 的次数
FGC从应用程序启动到采样时发生 Full GC 的次数

    -gccause

     这个选项用于查看垃圾收集的统计情况(这个和-gcutil选项一样),如果有发生垃圾收集,它还会显示最后一次及当前正在发生垃圾收集的原因,它比-gcutil会多出最后一次垃圾收集原因以及当前正在发生的垃圾收集的原因。

列名说明
LGCC最后一次垃圾收集的原因,可能为“unknown GCCause”、“System.gc()”等
GCC当前垃圾收集的原因

    -gcnew

列名说明
S0C当前新生代中survivor space 0的容量大小(KB)
S1C当前新生代中survivor space 1的容量大小(KB)
S0US0已经使用的大小(KB)
S1US1已经使用的大小(KB)
TTTenuring threshold,要了解这个参数,我们需要了解一点Java内存对象的结构,在Sun JVM中,(除了数组之外的)对象都有两个机器字(words)的头部。第一个字中包含这个对象的标示哈希码以及其他一些类似锁状态和等标识信息,第二个字中包含一个指向对象的类的引用,其中第二个字节就会被垃圾收集算法使用到。
在新生代中做垃圾收集的时候,每次复制一个对象后,将增加这个对象的收集计数,当一个对象在新生代中被复制了一定次数后,该算法即判定该对象是长周期的对象,把他移动到老生代,这个阈值叫着tenuring threshold。这个阈值用于表示某个/些在执行批定次数youngGC后还活着的对象,即使此时新生的的Survior没有满,也同样被认为是长周期对象,将会被移到老生代中。
MTTMaximum tenuring threshold,用于表示TT的最大值。
DSSDesired survivor size (KB).可以参与这里:http://blog.csdn.net/yangjun2/article/details/6542357
ECEden space当前容量的大小(KB)
EUEden space已经使用的大小(KB)
YGC从应用程序启动到采样时发生 Young GC 的次数
YGCT从应用程序启动到采样时 Young GC 所用的时间(单位秒)

    -gcnewcapacity

列名说明
NGCMN          新生代的最小容量大小(KB)
NGCMX    新生代的最大容量大小(KB)
NGC    当前新生代的容量大小(KB)
S0CMX新生代中SO的最大容量大小(KB)
S0C当前新生代中SO的容量大小(KB)
S1CMX新生代中S1的最大容量大小(KB)
S1C当前新生代中S1的容量大小(KB)
ECMX新生代中Eden的最大容量大小(KB)
EC当前新生代中Eden的容量大小(KB)
YGC从应用程序启动到采样时发生 Young GC 的次数
FGC从应用程序启动到采样时发生 Full GC 的次数

    -gcold

列名说明
PC当前持久代容量的大小(KB)
PU持久代使用容量的大小(KB)
OC当前老年代容量的大小(KB)
OU老年代使用容量的大小(KB)
YGC从应用程序启动到采样时发生 Young GC 的次数
FGC从应用程序启动到采样时发生 Full GC 的次数
FGCT从应用程序启动到采样时 Full GC 所用的时间(单位秒)
GCT从应用程序启动到采样时用于垃圾回收的总时间(单位秒),它的值等于YGC+FGC

    -gcoldcapacity

列名说明
OGCMN老生代的最小容量大小(KB)
OGCMX老生代的最大容量大小(KB)
OGC当前老生代的容量大小KB)
OC当前新生代的空间容量大小KB)
YGC从应用程序启动到采样时发生 Young GC 的次数
FGC从应用程序启动到采样时发生 Full GC 的次数
FGCT从应用程序启动到采样时 Full GC 所用的时间(单位秒)
GCT从应用程序启动到采样时用于垃圾回收的总时间(单位秒),它的值等于YGC+FGC

    -gcpermcapacity

    从应用程序启动到采样时发生 Full GC 的次数

列名说明
PGCMN持久代的最小容量大小(KB)
PGCMX持久代的最大容量大小(KB)
PGC当前持久代的容量大小KB)
PC当前持久代的空间容量大小KB)
YGC从应用程序启动到采样时发生 Young GC 的次数
FGC
FGCT从应用程序启动到采样时 Full GC 所用的时间(单位秒)
GCT从应用程序启动到采样时用于垃圾回收的总时间(单位秒),它的值等于YGC+FGC

    -gcutil

列名说明
S0Heap上的 Survivor space 0 区已使用空间的百分比
S1Heap上的 Survivor space 1 区已使用空间的百分比
EHeap上的 Eden space 区已使用空间的百分比
OHeap上的 Old space 区已使用空间的百分比
PPerm space 区已使用空间的百分比
YGC从应用程序启动到采样时发生 Young GC 的次数
YGCT从应用程序启动到采样时 Young GC 所用的时间(单位秒)
FGC从应用程序启动到采样时发生 Full GC 的次数
FGCT从应用程序启动到采样时 Full GC 所用的时间(单位秒)
GCT从应用程序启动到采样时用于垃圾回收的总时间(单位秒),它的值等于YGC+FGC

    -printcompilation

列名说明
Compiled编译任务执行的次数
Size方法的字节码所占的字节数
Type编译类型
Method指定确定被编译方法的类名及方法名,类名中使名“/”而不是“.”做为命名分隔符,方法名是被指定的类中的方法,这两个字段的格式是由HotSpot中的“-XX:+PrintComplation”选项确定的。

4、使用示例

示例1)、

示例2):

图中同时打印了young gc和full gc的总次数、总耗时。而,每次young gc消耗的时间,可以用相间隔的两行YGCT相减得到。每次full gc消耗的时间,可以用相隔的两行FGCT相减得到。例如红框中表示的第一行、第二行之间发生了1次young gc,消耗的时间为0.252-0.252=0.0秒。

常驻内存区(P)的使用率,始终停留在64.21%左右,说明常驻内存没有突变,比较正常。如果young gc和full gc能够正常发生,而且都能有效回收内存,常驻内存区变化不明显,则说明java内存释放情况正常,垃圾回收及时,java内存泄露的几率就会大大降低。但也不能说明一定没有内存泄露。

示例3)、

    以上,介绍了Jstat按百分比查看gc情况的功能。其实,它还有功能,例如加载类信息统计功能、内存池信息统计功能等,那些是以绝对值的形式打印出来的,比较少用,在此就不做介绍。

示例4)、jstat -class pid:显示加载class的数量,及所占空间等信息。

 示例5)、jstat -compiler pid:显示VM实时编译的数量等信息。

示例6)、查看远程服务器上的GC情况。

    这个需要先在远程服务器上面开启jstatd服务,可以选看这里如何开启jstatd服务,http://blog.csdn.net/fenglibing/article/details/17323515

    下面是一个执行示例:

C:\Documents and Settings\Administrator>jstat -gcutil 18272@the_ip:2021/jstatdName 1000

  S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT
  0.00   0.00   8.00   0.00  24.36      0    0.000     0    0.000    0.000
  0.00   0.00   8.00   0.00  24.36      0    0.000     0    0.000    0.000
  0.00   0.00   8.00   0.00  24.36      0    0.000     0    0.000    0.000
  0.00   0.00   8.00   0.00  24.36      0    0.000     0    0.000    0.000
  0.00   0.00   8.00   0.00  24.36      0    0.000     0    0.000    0.000
  0.00   0.00   8.00   0.00  24.36      0    0.000     0    0.000    0.000

    示例就不一一例举,有兴趣的可以自己尝试尝试。


Oracle上关于Jstat的使用说明:http://docs.oracle.com/javase/1.5.0/docs/tooldocs/share/jstat.html

转自: CSDN-jstat命令(Java Virtual Machine Statistics Monitoring Tool)

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”

mysql 忘记密码的处理方法

【说明】MySQL5.7忘记root密码的时候,处理方式跟之前的版本有些不一样,这边整理如下:

【1】修改参数文件跳过密码验证
vim /etc/my.cnf
# 在 [mysqld] 中加上一行跳过权限限制
skip-grant-tables
# 保存退出 重启mysql服务
service mysqld restart

【2】修改密码字段

# 用户登录
mysql -uroot -p (直接点击回车,密码为空)
update mysql.user set authentication_string=password(‘123456′) where user=’root’;
# 刷新权限
flush privileges;
# 但是在5.7版本中不存在password字段,所有我们要用以下修改进行重置密码

【3】最开始修改的配置文件my.cnf中的skip-grant-tables删除 重启mysql
service mysqld restart

【4】 当你登陆mysql之后你会发现,当你执行命令时会出现
ERROR 1820 (HY000): You must reset your password using ALTER USER statement;
# 这是提示你需要修改密码 当你执行了
SET PASSWORD = PASSWORD(‘root’);
# 如果出现
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
# 你需要执行两个参数来把mysql默认的密码强度的取消了才行 当然也可以把你的密码复杂度提高也行啊
set global validate_password_policy=0;
set global validate_password_mixed_case_count=2;

【5】经过以上操作,便完成了密码的变更;

从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