一个没有技术只会增删改查的后端
将java应用(springboot jar)注册成Windows服务

将springboot 打包成jar

  1. 修改pom.xml设置<packaging>jar</packaging>

  2. 使用mvn命令打包程序mvn clean package

  3. 在项目目录target下找到jar文件

下载WinSW

  1. github开源地址

  2. 下载地址

  3. 下载WinSW.NET4.exesample-minimal.xml文件

修改WinSW配置文件

通过NTML代理访问Maven库

公司用web代理,NTLM验证的,这样在普通CMD下无法使用mvn命令访问网上的maven库,使用CNTLM工具解决。

下载CNTLM工具,安装,修改安装路径下的cntlm.ini,改成实际的ntlm proxy地址,CNTLM会起一个proxy service监听3128端口。

然后配置maven的代理,在maven目录下\conf/settings.xml。

1
2
3
4
5
6
7
<proxy>  
<id>optional</id>
<active>true</active>
<protocol>http</protocol>
<host>127.0.0.1</host>
<port>3128</port>
</proxy>

这个可以让cmd下运行mvn时候让mvn去找本地的cntlm代理,因为cntlm代理已经连通了实际的内网web代理,这时可以搜索到外网respository的jar包了。

nginx反向代理webSocket配置

最近有一个需求,就是需要使用 nginx 反向代理 websocket,经过查找一番资料,目前已经测试通过,本文只做一个记录。

看官方文档说 Nginx 在 1.3.13 以后的版本才支持 websocket 反向代理,所以要想使用支持 websocket 的功能,必须升级到 1.3.13 以后的版本。

配置起来也特别简单。配置参考:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
server {
listen 80;
server_name test.test.cn;


location / {
proxy_pass http://test2.test.cn:8080;

proxy_read_timeout 3600s;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

}
}

简单解释一下:

nginx之proxy_pass指令完全拆解

一、proxy_pass的nginx官方指南

nginx中有两个模块都有proxy_pass指令。

ngx_http_proxy_module的proxy_pass:

1
2
3
4
5
语法: proxy_pass URL;
场景: location, if in location, limit_except
说明: 设置后端代理服务器的协议(protocol)和地址(address),以及location中可以匹配的一个可选的URI。协议可以是"http"或"https"。地址可以是一个域名或ip地址和端口,或者一个 unix-domain socket 路径。
详见官方文档: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
URI的匹配,本文第四部分重点讨论。

ngx_stream_proxy_module的proxy_pass:

录制JMeter脚本

一般自己手动的设置JMeter会比较麻烦,如果一边操作页面,提交表单,一边能够自动生成JMeter的脚本,则非常方便;

BadBoy:录制JMeter脚本的软件;

Donwload URL:http://www.badboy.com.au/

BadBoy界面如下:

PWA介绍及快速上手搭建一个PWA应用

前言

本示例不用安装任何东西

部分资源来自网络资源及PWA官网,不要把PWA想象的太复杂,跟着示例走一下,你行的。

PWA介绍

一个新的前端技术,PWA( 全称:Progressive Web App )也就是说这是个渐进式的网页应用程序。

C#去掉HTML标记

直接上代码:

junit-断言

断言是编写测试用例的核心实现方式,即期望值是多少,测试的结果是多少,以此来判断测试是否通过。

  1. 断言核心方法

  1. 示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package test;

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;

import java.util.Arrays;

import org.hamcrest.core.CombinableMatcher;
import org.junit.Test;

public class AssertTests {

@Test
public void testAssertArrayEquals() {
byte[] expected = "trial".getBytes();
byte[] actual = "trial".getBytes();
org.junit.Assert.assertArrayEquals("failure - byte arrays not same", expected, actual);
}

@Test
public void testAssertEquals() {
org.junit.Assert.assertEquals("failure - strings not same", 5l, 5l);
}

@Test
public void testAssertFalse() {
org.junit.Assert.assertFalse("failure - should be false", false);
}

@Test
public void testAssertNotNull() {
org.junit.Assert.assertNotNull("should not be null", new Object());
}

@Test
public void testAssertNotSame() {
org.junit.Assert.assertNotSame("should not be same Object", new Object(), new Object());
}

@Test
public void testAssertNull() {
org.junit.Assert.assertNull("should be null", null);
}

@Test
public void testAssertSame() {
Integer aNumber = Integer.valueOf(768);
org.junit.Assert.assertSame("should be same", aNumber, aNumber);
}

// JUnit Matchers assertThat
@Test
public void testAssertThatBothContainsString() {
org.junit.Assert.assertThat("albumen", both(containsString("a")).and(containsString("b")));
}

@Test
public void testAssertThathasItemsContainsString() {
org.junit.Assert.assertThat(Arrays.asList("one", "two", "three"), hasItems("one", "three"));
}

@Test
public void testAssertThatEveryItemContainsString() {
org.junit.Assert.assertThat(Arrays.asList(new String[] { "fun", "ban", "net" }), everyItem(containsString("n")));
}

// Core Hamcrest Matchers with assertThat
@Test
public void testAssertThatHamcrestCoreMatchers() {
assertThat("good", allOf(equalTo("good"), startsWith("good")));
assertThat("good", not(allOf(equalTo("bad"), equalTo("good"))));
assertThat("good", anyOf(equalTo("bad"), equalTo("good")));
assertThat(7, not(CombinableMatcher.<Integer> either(equalTo(3)).or(equalTo(4))));
assertThat(new Object(), not(sameInstance(new Object())));
}
}
SpringBoot项目中增加了WebSocket功能无法运行测试

测试类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.jermey;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;

import com.jermey.MyTest;

@RunWith(SpringRunner.class)
@SpringBootTest
public class FetchFolder {
@Autowired
private MyTest myTest;
@Test
public void test() throws Exception {
System.out.println(myTest.test());
}
}

问题原因:

默认情况下,@SpringBootTest不会启动服务器。

解决方法:

MySQL慢查询日志总结

慢查询日志概念

MySQL的慢查询日志是MySQL提供的一种日志记录,它用来记录在MySQL中响应时间超过阀值的语句,
具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志中。long_query_time的默认值为10,
意思是运行10S以上的语句。
默认情况下,Mysql数据库并不启动慢查询日志,需要我们手动来设置这个参数,
当然,如果不是调优需要的话,一般不建议启动该参数,因为开启慢查询日志会或多或少带来一定的性能影响。
慢查询日志支持将日志记录写入文件,也支持将日志记录写入数据库表。

慢查询日志相关参数

MySQL 慢查询的相关参数解释:

1
2
3
4
5
6
slow_query_log    :是否开启慢查询日志,1表示开启,0表示关闭。
log-slow-queries :旧版(5.6以下版本)MySQL数据库慢查询日志存储路径。可以不设置该参数,系统则会默认给一个缺省的文件host_name-slow.log
slow-query-log-file:新版(5.6及以上版本)MySQL数据库慢查询日志存储路径。可以不设置该参数,系统则会默认给一个缺省的文件host_name-slow.log
long_query_time :慢查询阈值,当查询时间多于设定的阈值时,记录日志。
log_queries_not_using_indexes:未使用索引的查询也被记录到慢查询日志中(可选项)。
log_output:日志存储方式。log_output='FILE'表示将日志存入文件,默认值是'FILE'。log_output='TABLE'表示将日志存入数据库,这样日志信息就会被写入到mysql.slow_log表中。MySQL数据库支持同时两种日志存储方式,配置的时候以逗号隔开即可,如:log_output='FILE,TABLE'。日志记录到系统的专用日志表中,要比记录到文件耗费更多的系统资源,因此对于需要启用慢查询日志,又需要能够获得更高的系统性能,那么建议优先记录到文件。