0%

前言


古语有云:

道为术之灵,术为道之体;以道统术,以术得道。

其中:“道”指“规律、道理、理论”,“术”指“方法、技巧、技术”。意思是:“道”是“术”的灵魂,“术”是“道”的肉体;可以用“道”来统管“术”,也可以从“术”中获得“道”。

阅读全文 »

有一个需求需要将前端传过来的10张照片,然后后端进行处理以后压缩成一个压缩包通过网络流传输出去。之前没有接触过用Java压缩文件的,所以就直接上网找了一个例子改了一下用了,
改完以后也能使用,但是随着前端所传图片的大小越来越大的时候,耗费的时间也在急剧增加,最后测了一下压缩20M的文件竟然需要30秒的时间。压缩文件的代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static void zipFileNoBuffer() {
File zipFile = new File(ZIP_FILE);
try (ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFile))) {
//开始时间
long beginTime = System.currentTimeMillis();

for (int i = 0; i < 10; i++) {
try (InputStream input = new FileInputStream(JPG_FILE)) {
zipOut.putNextEntry(new ZipEntry(FILE_NAME + i));
int temp = 0;
while ((temp = input.read()) != -1) {
zipOut.write(temp);
}
}
}
printInfo(beginTime);
} catch (Exception e) {
e.printStackTrace();
}
}

这里找了一张2M大小的图片,并且循环十次进行测试。打印的结果如下,时间大概是30秒。

1
2
fileSize:20M
consum time:29599

第一次优化过程-从30秒到2秒

阅读全文 »

普通的bean的初始化是在容器启动初始化阶段执行的,而被lazy-init修饰的bean 则是在从容器里第一次进行context.getBean(“”)时进行触发。Spring 启动的时候会把所有bean信息(包括XML和注解)解析转化成Spring能够识别的BeanDefinition并存到Hashmap里供下面的初始化时用。接下来对每个BeanDefinition进行处理,如果是懒加载的则在容器初始化阶段不处理,其他的则在容器初始化阶段进行初始化并依赖注入。
本文我说了很多次 Spring 容器初始化和bean初始化,容器的初始化有可能包括bean的初始化主要取决于该bean是否是懒加载的,特此说明怕误会 。

先睹为快

话不多说先写个例子看下这属性到底有什么作用,我们定义了一个叫做coffee的普通bean,代码如下:

普通非懒加载bean的演示

1
2
3
4
5
6
7
8
9
package com.test.spring;

public class Coffee {

public Coffee() {
System.out.println("正在初始化bean !!!调用无参构造函数");
}

}
阅读全文 »

答案: controller默认是单例的,不要使用非静态的成员变量,否则会发生数据逻辑混乱,正因为单例所以不是线程安全的。

我们下面来简单的验证下:

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
package com.riemann.springbootdemo.controller;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
* @author riemann
* @date 2019/07/29 22:56
*/
@Controller
public class ScopeTestController {

private int num = 0;

@RequestMapping("/testScope")
public void testScope() {
System.out.println(++num);
}

@RequestMapping("/testScope2")
public void testScope2() {
System.out.println(++num);
}

}

我们首先访问 http://localhost:8080/testScope, 得到的答案是1;
然后我们再访问 http://localhost:8080/testScope2, 得到的答案是2。
得到的不同的值,这是线程不安全的。

接下来我们再来给controller增加作用多例 @Scope(“prototype”)

阅读全文 »

在用docker方式部署spring boot应用的时候发现程序时间不对,这是和时区有关
我们修改Dockerfile文件内容设置一下时区

1
2
3
4
5
6
7
8
FROM openjdk:8-jdk-alpine

#设置时区
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone

COPY target/docker-spring-boot-demo-0.0.1.jar app.jar

ENTRYPOINT ["sh","-c","java -jar app.jar"]

再次启动发现时间正常了

基本概念

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。

架构

一个完整的Docker有以下几个部分组成:

Docker Client客户端
Docker Daemon守护进程
Docker Image镜像
Docker Container容器

阅读全文 »

Prometheus 简介

Prometheus是一个开源监控系统,它前身是SoundCloud的警告工具包。从2012年开始,许多公司和组织开始使用Prometheus。该项目的开发人员和用户社区非常活跃,越来越多的开发人员和用户参与到该项目中。目前它是一个独立的开源项目,且不依赖与任何公司。为了强调这点和明确该项目治理结构,Prometheus在2016年继Kurberntes之后,加入了Cloud Native Computing Foundation。
开源地址:https://github.com/prometheus

主要特性:

  • 多维度数据模型
  • 时间序列数据通过 metric 名和键值对来区分。
  • 所有的 metrics 都可以设置任意的多维标签。
  • 数据模型更随意,不需要刻意设置为以点分隔的字符串。
  • 可以对数据模型进行聚合,切割和切片操作。
  • 支持双精度浮点类型,标签可以设为全 unicode。
  • 灵活的查询语言(PromQL):在同一个查询语句,可以对多个 metrics 进行乘法、加法、连接、取分数位等操作。
  • 不依赖任何分布式存储
  • 通过拉取方式采集数据,或者通过中间网关推送方式采集数据
  • 通过服务发现或者静态配置来发现监控目标
  • 支持多种图形界面展示方式

整体架构

阅读全文 »