JoyLau's Blog

JoyLau 的技术学习与思考

通过注解读取文件

1
2
@Value("classpath:static/json/addTask.json")
Resource addTaskJson;

其他配置

前缀 例子 说明
classpath: classpath:com/myapp/config.xml 从classpath中加载
file: file:/data/config.xml 作为 URL 从文件系统中加载
http: http://myserver/logo.png 作为 URL 加载
(none) /data/config.xml 根据 ApplicationContext 进行判断

摘自于Spring Framework参考手册

转化为 字符串 转化为 JSON 对象

1
2
String jsonStr = new String(IOUtils.readFully(addTaskJson.getInputStream(), -1,true));
JSONObject json = JSONObject.parseObject(jsonStr);

注意: 该方法需要 jdk1.8的环境

SpringBoot 连接 Oracle

pom 文件配置

1
2
3
4
5
6
7
8
9
10
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>12.1.0.2</version>
</dependency>

注意: com.oracle.ojdbc6.12.1.0.2 在中央仓库没有,需要单独下载下来,再安装到本地仓库

yml文件配置

1
2
3
4
5
6
7
8
9
10
spring:
datasource:
driver-class-name: oracle.jdbc.OracleDriver
url: jdbc:oracle:thin:@192.168.10.240:1522:orcl12c
username: C##itmscz
password: itmscz
jpa:
hibernate:
ddl-auto: update
show-sql: true

接下来的套路都一样了,写好model实体类,注册个接口,然后就可以直接增删改查了

model :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Entity(name = "t_samp_recog")
@Data
public class SampRecog {
@Id
@GeneratedValue
private int id; //主键
private String batch; // 批次
private String img_url; // 图片路径
private String plate_nbr; // 车辆号牌
private boolean plate_nbr_right; // 车辆号牌是否正确
private String brand; // 品牌
private boolean brand_right; // 品牌是否正确
private String veh_type; // 车辆类型
private boolean veh_type_right; // 车辆类型是否正确
private String veh_color; // 车身颜色
private boolean veh_color_right; // 车身颜色是否正确
private String sticker_pos; // 车标位置
private boolean sticker_pos_right; // 车标位置是否全部正确
private boolean is_right; // 是否全部正确
private int check_status; //核对状态 1.未核对,2,正在核对,3、已经核对
}

dao :

1
2
public interface SampRecogDAO extends JpaRepository<SampRecog,Integer> {
}

看来 SpringBoot 整合数据源的套路都一样,下次整合其他的猜都知道怎么做了

以前一直用的 Navicat Premiun,里面虽然支持 Oracle ,但是支持 Oracle 版本都比较老啦,新一点的根本连接不上去,今天在网上找到个绿色版的 Navicat for Oracle,赶紧记下来,mark一下

地址

百度云盘:链接: https://pan.baidu.com/s/1mhPS9wW 密码: gtq4

7z的是我替换操作后的

操作

下载 3个文件 :
Navicat for Oracle.zip

instantclient-basic-nt-12.1.0.2.0.zip

instantclient-sqlplus-nt-12.1.0.2.0.zip

直接把 instantclient-basic-nt-12.1.0.2.0.zip 解压到 Navicat for Oracle 的解压目录的instantclient_10_2目录下

然后这个目录下多了instantclient_12_1 这个目录

然后再把instantclient-sqlplus-nt-12.1.0.2.0.zip 解压到 instantclient_12_1下

完成

最后打开Navicat for Oracle 单击 工具->选项-> OCI

2个路径分别选:

\instantclient_12_1.oci.dll

\instantclient_12_1.sqlplus.exe

然后就可以连接使用了

配置说明

配置Elasticsearch的集群名称,默认是elasticsearch,Elasticsearch会自动发现在同一网段下的Elasticsearch 节点,如果在同一网段下有多个集群,就可以用这个属性来区分不同的集群。
cluster.name: elasticsearch

节点名,默认随机指定一个name列表中名字,不能重复。
node.name: "node1"

指定该节点是否有资格被选举成为node,默认是true,es是默认集群中的第一台机器为master,如果这台机挂了就会重新选举master。
node.master: true

指定该节点是否存储索引数据,默认为true。
node.data: true

设置默认索引分片个数,默认为5片。
index.number_of_shards: 5

设置默认索引副本个数,默认为1个副本。
index.number_of_replicas: 1

设置配置文件的存储路径,默认是es根目录下的config文件夹。
path.conf: /path/to/conf

设置索引数据的存储路径,默认是es根目录下的data文件夹
path.data: /path/to/data

可以设置多个存储路径,用逗号(半角)隔开,如下面这种配置方式:
path.data: /path/to/data1,/path/to/data2

设置临时文件的存储路径,默认是es根目录下的work文件夹。
path.work: /path/to/work

设置日志文件的存储路径,默认是es根目录下的logs文件夹
path.logs: /path/to/logs

设置插件的存放路径,默认是es根目录下的plugins文件夹
path.plugins: /path/to/plugins

设置为true来锁住内存。因为当jvm开始swapping时es的效率会降低,所以要保证它不swap,可以把ES_MIN_MEM和ES_MAX_MEM两个环境变量设置成同一个值,并且保证机器有足够的内存分配给es。同时也要允许elasticsearch的进程可以锁住内存,linux下可以通过`ulimit -l unlimited`命令。
bootstrap.mlockall: true

设置绑定的ip地址,可以是ipv4或ipv6的,默认为0.0.0.0。
network.bind_host: 192.168.0.1

设置其它节点和该节点交互的ip地址,如果不设置它会自动判断,值必须是个真实的ip地址。
network.publish_host: 192.168.0.1

这个参数是用来同时设置bind_host和publish_host上面两个参数。
network.host: 192.168.0.1

设置节点间交互的tcp端口,默认是9300,(集群的时候,注意端口区分)。
transport.tcp.port: 9300

设置是否压缩tcp传输时的数据,默认为false,不压缩。
transport.tcp.compress: true

设置对外服务的http端口,默认为9200(集群的时候,同台机器,注意端口区分)。
http.port: 9200

设置内容的最大容量,默认100mb
http.max_content_length: 100mb

是否使用http协议对外提供服务,默认为true,开启。
http.enabled: false

gateway的类型,默认为local即为本地文件系统,可以设置为本地文件系统,分布式文件系统,hadoop的HDFS,和amazon的s3服务器。
gateway.type: local

设置集群中N个节点启动时进行数据恢复,默认为1。
gateway.recover_after_nodes: 1

设置初始化数据恢复进程的超时时间,默认是5分钟。
gateway.recover_after_time: 5m

设置这个集群中节点的数量,默认为2,一旦这N个节点启动,就会立即进行数据恢复。
gateway.expected_nodes: 2

初始化数据恢复时,并发恢复线程的个数,默认为4。
cluster.routing.allocation.node_initial_primaries_recoveries: 4

添加删除节点或负载均衡时并发恢复线程的个数,默认为4。
cluster.routing.allocation.node_concurrent_recoveries: 2

设置数据恢复时限制的带宽,如入100mb,默认为0,即无限制。
indices.recovery.max_size_per_sec: 0

设置这个参数来限制从其它分片恢复数据时最大同时打开并发流的个数,默认为5。
indices.recovery.concurrent_streams: 5

设置这个参数来保证集群中的节点可以知道其它N个有master资格的节点。默认为1,对于大的集群来说,可以设置大一点的值(2-4)
discovery.zen.minimum_master_nodes: 1

设置集群中自动发现其它节点时ping连接超时时间,默认为3秒,对于比较差的网络环境可以高点的值来防止自动发现时出错。
discovery.zen.ping.timeout: 3s

设置是否打开多播发现节点,默认是true。
discovery.zen.ping.multicast.enabled: false

设置集群中master节点的初始列表,可以通过这些节点来自动发现新加入集群的节点。
discovery.zen.ping.unicast.hosts: ["host1", "host2:port", "host3[portX-portY]"]

低配置云服务器上安装遇到的坑:

  1. 启动elasticsearch直接退出,并返回killed,这里一般是由于内存不足导致的
    修改es_home/config/jvm.options
    -Xms2g
    -Xmx2g

  2. max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]解决办法是手动修改/etc/sysctl.conf文件,最后面加上一行代码。
    vm.max_map_count=655360
    修改/etc/sysctl.conf,修改完成之后,参数可以使用sysctl -p命令来让参数生效

  3. initial heap size [536870912] not equal to maximum heap size [1073741824]; this can cause resize pauses and prevents mlockall from locking the entire heap
    vi config/jvm.options
    -Xms 和 -Xmx需要配置的相等,不然无法启动成功

【更新一下内容 2018年4月28日】

  1. elasticsearch 5 版本以上不能以 root 用户启动,需要新建一个用户
    useradd elasticsearch
    passwd elasticsearch
    chown elasticsearch path -R

  2. elasticsearch 在 linux 下以后台启动的命令
    sh elasticsearch -d
    确认日志没有报错,然后head插件可以连接的上就可以了

2018-06-21 更新

  1. ElasticSearch 允许跨域
    http.cors.enabled: true #开启跨域访问支持,默认为false
    http.cors.allow-origin: /.*/ #跨域访问允许的域名地址,(允许所有域名)以上使用正则

  2. rpm 安装的 elasticsearch 可以自动以系统服务启动和以root用户启动

前言

第一天学习 Hadoop 看了不少资料和文档,在这里想总结一下这一天的所学

感受

以前一直以为 JavaWeb 和大数据这是2条路子,学了大数据之后就要放下 JavaWeb,就像在项目中使用 Struts2 和 SpringMVC,2者只能选一个使用,在看了一些资料之后,我发现我的认识错了,其实 JavaWeb 和大数据技术就像 SpringMVC 和Spring Boot
2者是并行不悖的。大数据技术囊括很多技术,JavaWeb只是其中的一部分,要学习大数据需要学习的技术还有很多。

总结

Hadoop是干什么的

一句话概括:适合大数据的分布式存储与计算平台

Hadoop的2个重要部分

  • HDFS : 分布式文件系统
  • MapReduce : 并行计算框架

HDFS

主从结构:

主节点: 只有一个 namedode

从节点: 多个 datanode

namenode:

负责接收用户请求

维护文件系统的目录结构

管理文件与 block 之间的关系,block 与 datanode 之间的关系

datanode:

存储文件

文件被分成若干 Block 存储在磁盘上

为保证数据安全,文件会被备份成多个副本

MapReduce

主从结构:

主节点: 只有一个 JobTracker

从节点: 有多个 TaskTracker

JobTracker:

接受用户提交的任务

把计算任务分配给 TaskTracker 执行

监控 TaskTracker 的执行情况

TaskTracker:

执行 JobTracker 分配的任务

开始使用

引入依赖

1
2
3
4
5
6
7
8
9
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>3.0.9</version>
</dependency>

这里需要注意的是:
SpringBoot 的版本和 elasticsearch 的版本问题,在springboot 1.3.5 版本之前支持elasticsearch2.0 以下的版本,springboot1.3.5之后的版本支持elasticsearch5.0以下的版本
net.java.dev.jna 这个依赖是因为启动后报类不存在,加个jna依赖加上后就好了

配置文件

1
2
3
4
5
spring:
data:
elasticsearch:
cluster-name: elasticsearch
cluster-nodes: localhost:9300

这里需要注意的是:
elasticsearch对外提供的api的端口的是9200,提供各个集群间和客户端通信的是9300
配置文件里 cluster-nodes 配置项如果不填写的话,springboot应用启动时会自动创建内部的 elasticsearch 客户端,你会发现即是本地没开 elasticsearch 服务也能跑起来
配置多个集群的话 cluster-nodes 就配置多条信息,用逗号隔开

在 SpringBoot 项目中使用

  • 主要的一个接口ElasticsearchRepository<T,ID>,第一个是要存储的实体类,第二个参数是 ID 类型
  • 还有个 ElasticsearchCrudRepository,顾名思义就是增删改查
  • 自定义一个接口实现上述接口
  • 定义实体类
  • 自定义实现类可直接注入使用
  • 默认的已经存在了增删改查的方法了,可以直接使用
  • 想要更多的功能可以在接口中实现更多的自定义

自定义一个 DAO :

1
2
public interface SongDao extends ElasticsearchRepository<Song,Integer> {
}

定义一个实体类 :

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
@Data
@NoArgsConstructor
@Document(indexName = "songdb",type = "song")
public class Song {
@Id
private int id;

private String name;

private String author;

private long time;

private String commentKeyId;

private String mp3URL;

/*歌曲封面地址*/
private String picURL;

/*歌曲描述*/
private String describe;

/*专辑*/
private String album;

/*歌词*/
private String lyric;

/*mvid*/
private int mvId;
}

注意:
@Document注解里面的几个属性,类比mysql的话是这样:
index –> DB
type –> Table
Document –> row
@Id注解加上后,在Elasticsearch里相应于该列就是主键了,在查询时就可以直接用主键查询,后面一篇会讲到。其实和mysql非常类似,基本就是一个数据库
indexName在上述注解中需要小写

使用的话 注入SongDAO ,之后就可以看到相应的方法了
使用起来就是如此简单,感觉使用起来很像MongoDB配置

有一些注解的配置

有时候使用起来会有一些问题

  • 在默认策略下, Java 实体类叫什么名字,生成后的表名就叫什么,但我们可能并不想这样
  • 同样的道理,有时属性名和字段也并不想一样的

注解解决这些问题

  • @Id : 标明表的 ID , 自带索引,无需维护
  • @Document : 解决第一个问题
  • @Field : 解决第二个问题,默认不加@Field 有一写默认配置,一旦添加了@Filed注解,所有的默认值都不再生效。此外,如果添加了@Filed注解,那么type字段必须指定

入门使用就写到这

本文转自 阮一峰- 开源许可证教程

开源许可证教程

作为一个开发者,如果你打算开源自己的代码,千万不要忘记,选择一种开源许可证(license)。

许多开发者对开源许可证了解很少,不清楚有哪些许可证,应该怎么选择。本文介绍开源许可证的基本知识,主要参考了 OpenSource.com (12)。

一、什么是开源许可证

开源许可证是一种法律许可。通过它,版权拥有人明确允许,用户可以免费地使用、修改、共享版权软件。

版权法默认禁止共享,也就是说,没有许可证的软件,就等同于保留版权,虽然开源了,用户只能看看源码,不能用,一用就会侵犯版权。所以软件开源的话,必须明确地授予用户开源许可证。

二、开源许可证的种类

目前,国际公认的开源许可证共有80多种。它们的共同特征是,都允许用户免费地使用、修改、共享源码,但是都有各自的使用条件。

如果一种开源许可证没有任何使用条件,连保留作者信息都不需要,那么就等同于放弃版权了。这时,软件可以直接声明进入“公共领域”(public domain)。

根据使用条件的不同,开源许可证分成两大类。

  • 宽松式(permissive)许可证
  • Copyleft 许可证

三、宽松式许可证

3.1 特点

宽松式许可证(permissive license)是最基本的类型,对用户几乎没有限制。用户可以修改代码后闭源。

它有三个基本特点。

(1)没有使用限制

用户可以使用代码,做任何想做的事情。

(2)没有担保

不保证代码质量,用户自担风险。

(3)披露要求(notice requirement)

用户必须披露原始作者。

3.2 常见许可证

常见的宽松式许可证有四种。它们都允许用户任意使用代码,区别在于要求用户遵守的条件不同。

(1)BSD(二条款版)

分发软件时,必须保留原始的许可证声明。

(2) BSD(三条款版)

分发软件时,必须保留原始的许可证声明。不得使用原始作者的名字为软件促销。

(3)MIT

分发软件时,必须保留原始的许可证声明,与 BSD(二条款版)基本一致。

(4)Apache 2

分发软件时,必须保留原始的许可证声明。凡是修改过的文件,必须向用户说明该文件修改过;没有修改过的文件,必须保持许可证不变。

四、Copyleft 许可证

4.1 Copyleft 的含义

Copyleft 是理查德·斯托曼发明的一个词,作为 Copyright (版权)的反义词。

Copyright 直译是“复制权”,这是版权制度的核心,意为不经许可,用户无权复制。作为反义词,Copyleft 的含义是不经许可,用户可以随意复制。

但是,它带有前提条件,比宽松式许可证的限制要多。

  • 如果分发二进制格式,必须提供源码
  • 修改后的源码,必须与修改前保持许可证一致
  • 不得在原始许可证以外,附加其他限制

上面三个条件的核心就是:修改后的 Copyleft 代码不得闭源。

4.2 常见许可证

常见的 Copyleft 许可证也有四种(对用户的限制从最强到最弱排序)。

(1)Affero GPL (AGPL)

如果云服务(即 SAAS)用到的代码是该许可证,那么云服务的代码也必须开源。

(2)GPL

如果项目包含了 GPL 许可证的代码,那么整个项目都必须使用 GPL 许可证。

(3)LGPL

如果项目采用动态链接调用该许可证的库,项目可以不用开源。

(4)Mozilla(MPL)

只要该许可证的代码在单独的文件中,新增的其他文件可以不用开源。

五、常见问题

本节回答一些开源许可证的常见问题。

5.1 什么叫分发(distribution)?

除了 Affero GPL (AGPL) ,其他许可证都规定只有在“分发”时,才需要遵守许可证。换言之,如果不“分发”,就不需要遵守。

简单说,分发就是指将版权作品从一个人转移到另一个人。这意味着,如果你是自己使用,不提供给他人,就没有分发。另外,这里的“人”也指“法人”,因此如果使用方是公司,且只在公司内部使用,也不需要遵守许可证。

云服务(SaaS)是否构成“分发”呢?答案是不构成。所以你使用开源软件提供云服务,不必提供源码。但是,Affero GPL (AGPL) 许可证除外,它规定云服务也必须提供源码。

5.2 开源软件的专利如何处理?

某些许可证(Apache 2 和 GPL v3)包含明确的条款,授予用户许可,使用软件所包含的所有专利。

另一些许可证(BSD、MIT 和 GPL v2)根本没提到专利。但是一般认为,它们默认给予用户专利许可,不构成侵犯专利。

总得来说,除非有明确的“保留专利”的条款,使用开源软件都不会构成侵犯专利。

5.3 什么是披露要求?

所有的开源许可证都带有“披露要求”(notice requirement),即要求软件的分发者必须向用户披露,软件里面有开源代码。

一般来说,你只要在软件里面提供完整的原始许可证文本,并且披露原始作者,就满足了“披露要求”。

5.4 GPL 病毒是真的吗?

GPL 许可证规定,只要你的项目包含了 GPL 代码,整个项目就都变成了 GPL。有人把这种传染性比喻成“GPL 病毒”。

很多公司希望避开这个条款,既使用 GPL 软件,又不把自己的专有代码开源。理论上,这是做不到的。因为 GPL 的设计目的,就是为了防止出现这种情况。

但是实际上,不遵守 GPL,最坏情况就是被起诉。如果你向法院表示无法履行 GPL 的条件,法官只会判决你停止使用 GPL 代码(法律上叫做“停止侵害”),而不会强制要求你将源码开源,因为《版权法》里面没有相应的规定。

怎么使用?

pom 中引入插件:

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
<plugin>
<groupId>cn.joylau.code</groupId>
<artifactId>joylau-compressor-plugins</artifactId>
<version>1.2.RELEASE</version>
<executions>
<execution>
<id>resource-compressor</id>
<phase>compile</phase>
<goals>
<goal>resource-compressor</goal>
</goals>
</execution>
</executions>
<configuration>
<cssConfigs>
<cssConfig>
<dir>/static/css</dir>
<include>*.css</include>
<exclude>*.min.css</exclude>
</cssConfig>
</cssConfigs>
<jsConfigs>
<jsConfig>
<dir>/static/js</dir>
<include>*.js</include>
<exclude>*.min.js</exclude>
<munge>true</munge>
</jsConfig>
</jsConfigs>
<htmlConfigs>
<htmlConfig>
<dir>/templates</dir>
<include>*.html</include>
<removeIntertagSpaces>true</removeIntertagSpaces>
<compressJavaScript>false</compressJavaScript>
<compressCss>true</compressCss>
</htmlConfig>
</htmlConfigs>
</configuration>
</plugin>

配置解释

  • phase : compile 表明该插件在 compile 时调用

  • goal : 固定为 resource-compressor 不需要改变

  • cssConfigs , 可配置多个 cssConfig

    • cssConfig
      • dir: css文件目录
      • include:包含的css文件,支持通配符
      • exclude:排除的css文件,支持通配符
  • jsConfigs , 可配置多个 jsConfig

    • jsConfig
      • dir: js文件目录
      • include:包含的js文件,支持通配符
      • exclude:排除的js文件,支持通配符
      • munge: 是否进行代码混淆,缺省值为 false
      • preserveAllSemiColons : 保留所有的分号,缺省值为 false
      • disableOptimizations : 禁用自带的所有优化措施,缺省值为 false
  • htmlConfigs , 可配置多个 htmlConfig

    • htmlConfig
      • dir: js文件目录
      • include:包含的js文件,支持通配符
      • exclude:排除的js文件,支持通配符
      • removeComments: 是否移除注释,缺省值为 true
      • removeIntertagSpaces : 是否移除标签之间的空格,缺省值为 false
      • compressJavaScript : 是否对html里的js代码进行压缩,缺省值为 false
      • compressCss : 是否对html里的css代码进行压缩,缺省值为 false

压缩信息

当看到以下图片所示的信息后,则压缩成功

joylau-compressor-plugins

例如 :[INFO] common.js(8.71KB==>4.58KB,47.39%)

表示 :common.js 源文件大小8.71KB,压缩后大小 4.58KB,压缩率47.39%

GitHub 地址

源码已开源,地址 : https://github.com/JoyLau/joylau-compressor-plugins

  • 今天在浏览网站时,http://ai.baidu.com/ ,看到一个CSS3的效果:将鼠标放到图片上,图片会稍稍方大一点,当时很好奇是怎么做的
  • 当即百度了一下,有人用js做的,有人用css做的,首先js做的肯定不够好,一看效果就是css3的效果
  • 于是自己查看了下 这块 div 的效果
  • 将压缩的css展开来
  • 原来是这样的:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 鼠标移上去各浏览器的延时效果
.solution-img {
height: 100%;
-webkit-transform-origin: 50% 50%;
-moz-transform-origin: 50% 50%;
-ms-transform-origin: 50% 50%;
transform-origin: 50% 50%;
-webkit-transition: -webkit-transform .2s;
transition: -webkit-transform .2s;
-moz-transition: transform .2s,-moz-transform .2s;
transition: transform .2s;
transition: transform .2s,-webkit-transform .2s,-moz-transform .2s
}

# 鼠标移上去各浏览器的放大倍数
.solution-item:hover .solution-img {
-webkit-transform: scale(1.1);
-moz-transform: scale(1.1);
-ms-transform: scale(1.1);
transform: scale(1.1)
}
0%