SpringBoot 笔记(九):分布式

SpringBoot 笔记(九):分布式

我们可以使用 SpringBoot构建分布式应用,也就是我们在开发的时候可以进行多个模块的拆分,每一个功能做一个模块,然后我们使用一些分布式的框架,进行远程调用,所谓的远程调用就是RPC调用,而不是以前的WebService这个形式的.。其实这种分布式的RPC框架有很多,除了我们创常见的Doubbo还有就是我们Spring 项目自带的 SpringCloud 也是类似的东西。

Read More

SpringBoot 笔记(八):任务

SpringBoot 笔记 (八):任务

1.异步任务

1.开启异步任务注解

@EnableAsync

2.对Service层方法开启异步

@Async

1
2
3
4
5
6
7
8
9
@Service
public class TaskService {
@Async
public void task() throws InterruptedException {
System.out.println("start");
Thread.sleep(3000);
System.out.println("end");
}
}
1
2
3
4
5
6
7
8
@EnableAsync
@SpringBootApplication
public class TaskApplication {

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

2.定时任务

1.开启调度

@EnableScheduling

2.@Scheduled(cron = “”)

调度注解,放在Service层即可。

3.cron格式

秒(0-59) 分(0-59) 时(0-23) 日(1-31) 月(1-12) 周(0-7 其中0/7表示周日)

这几个位置可写的值不仅仅是上面的数字,还可以是表达式:

  • 枚举:1,2,3,4
  • 范围:2-5
  • 任意: *
  • 步长: /3 每3步
  • 冲突:? 当日和星期回冲突的时候

一些例子:

1 * * *? * 2-7 每周的周二到周天的每一分钟的第一秒触发

1-7 * * ? * 3 每周三的每分钟的1-7秒触发

0 0/5 14,18 ? * 1-6 每周的1-6 14点和18点 每个五分钟执行一次

0 15 10?* 1-6 每个月的周一至周六10:15分执行一次

0 0 2?* 6 每个月的最后一个周六凌晨2点执行一次

3.邮件发送

1.配置原理

配置pom文件

1
2
3
4
5
6
7
8
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
</dependency>

查看MailSenderAutoConfiguration的自动配置类

1
2
3
4
5
6
7
8
9
10
11
@Bean
public JavaMailSenderImpl mailSender() {
JavaMailSenderImpl sender = new JavaMailSenderImpl();
if (this.session != null) {
sender.setSession(this.session);
}
else {
applyProperties(sender);
}
return sender;
}

可以看到主要就是注入了一个 JavaMailSenderImpl 这个类的实例,然后我们就可以借助这个实例进行发送邮件。

2.配置属性

1
2
3
4
5
6
7
spring:
mail:
host:
username:
password:
default-encoding: utf-8
protocol: smtp

3.发送邮件

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
@Autowired
JavaMailSenderImpl javaMailSender;

/**
* 简单的文本文件的发送
*/
@Test
public void senderSimple(){
SimpleMailMessage message = new SimpleMailMessage();
message.setSubject("开会");
message.setText("你好开会");
message.setFrom("lwenxu");
message.setTo("xpf199741@outlook.com");
javaMailSender.send(message);
}

@Test
public void senderMulti() throws MessagingException {
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);

mimeMessageHelper.setSubject("开会");
mimeMessageHelper.setText("你好开会");
mimeMessageHelper.setFrom("lwenxu");
mimeMessageHelper.setTo("11@qq.com");
mimeMessageHelper.addAttachment("1.jpg", new File("C:\\asd.jpg"));

javaMailSender.send(mimeMessage);
}

SpringBoot 笔记(七):搜索

SpringBoot 笔记 (七):搜索

这里我们的搜索就是用 ElasticSearch 这个工具,这个其实是在 Lauce 的基础上构建的一个搜索引擎。

1. ES入门

1.docker安装

1
2
docker pull registry.docker-cn.com/library/elasticsearch
docker run -e ES_JAVA_OPTS="-Xms256m -Xmx256m" -d -p 9200:9200 -p 9300:9300 --name ES_dev

这里指定了es的初始的java堆大小和最大堆大小,否则就是默认的 2G 。

2.基本概念

ES 是一个面向文档的数据库,他的文档的格式就是JSON的格式。

1.索引

这个索引指的是动词,也就是我们把数据存放到ES中的一个过程。

2.索引

这个索引是名词,指的是我们的ES中的一个数据库。

3.类型

这个就相当与我们的一个表

4.文档

就是我们的数据记录。

简单的可以用一张表来表示:

image

SpringBoot 笔记 ( 五 ):缓存

SpringBoot 笔记 (五): 缓存

1.JSR107介绍

1.核心概念

JSR107这个规范有五个核心概念分别是:

  • CacheProvider 它用来管理缓存的Manager也就是用来创建,删除,管理,配置CacheManager 的
  • CacheManager 是用来管理各个缓存,创建,删除,管理,配置Cache的
  • Cache 是各个具体的缓存组件
  • Entry 是缓存中具体的一个缓存项
  • Expire 缓存的过期时间

Read More

Kafka 入门

1. Kafka架构

  1. 生产者(producer):生产资源的
  2. 消费者(consumer):消费资源
  3. broker(缓冲):中间缓冲器
  4. topic(标记):谁来消费

2. 配置Kafka

1. 配置ZK

  1. 解压
  2. 配置ZK_HOME
  3. 配置PATH
  4. 修改 zk.cfg 修改存储位置
  5. zkServer.sh 启动

2. 配置Kafka

  1. 配置HOME以及PATH
  2. 修改 server.porperties 注意以下几个条目
1
2
3
4
5
6
$KAFKA_HOME/config/server.properties
broker.id=0
listeners
host.name
1og.dirs
zookeeper.connect
  1. 启动Kafka
1
kafka-server-start.sh $KAFKA_HOME/config/server.properties
  1. 生产消息
1
kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic hello
  1. 启动消费者
1
kafka-console-consumer.sh --zookeeper localhost:2181 --topic hello --from-beginning

Flume 入门

1. 基本架构

1. 结构

source 源数据:目录/

channel 数据管道

sink 数据输出

2. 几种结构形式

  1. 单个的Flume
  2. 多个Flume串行工作,前一个Flume的sink作为后一个的source
  3. 多个Flume并行工作然后最后用一个Flume进行合并这行并行收集的数据
  4. 多个Flume并行工作,分别传送到不同的目的地

2. 安装

1. 安装JDK

解压到 /app
将java配置系统环境变量中:
/.bash_profile
export JAVA_HOME=/home/hadoop/app/jdk1.8.0_144
export PATH=$JAVA_HOME/bin:$PATH
source下让其配置生效
检测:java -version

2. 安装Flume

1. 安装

export FLUME_HOME=/home/hadoop/app/apache-flume-1.6.0-cdh5.7.0-b

export PATH=$FLUME_HOME/bin:$PATH
source下让其配置生效

2. 配置

flume-env.sh的配置:export JAVA_HOME=/home/hadoop/app/jdk1.8.0_144

3. 使用Flume

使用Flume的关键其实就是书写配置文件,然后启动不同的配置文件的进程就是不同的任务。

1. 配置

  • 配置Source
  • 配置Channel
  • 配置Sink
  • 把上面的组件串联起来

给一个简单的Conf的例子,并做一些注释。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#a1:agent名称 r1:source的名称 k1:sink的名称 c1:channel的名称
#Name the components on this agent
al.sources=r1
al.sinks=k1
al.channels=c1
#Describe/configure the source
al.sources.rl.type=netcat
al.sources.r1.bind=localhost
al.sources.r1.port =44444
#Describe the sink
al.sinks.k1.type=logger
# Use a channel which buffers events in memory
al.channels.c1.type=memory
#Bind the source and sink to the channel
al.sources.r1.channel.=c1
al.sinks.k1.channel=c1

2. 启动

1
2
3
4
5
flume-ng agent \
--name a1 \
-c $FLUME_HOME/conf \
-f $FLUME_HOME/conf/example.conf \
-Dflume.root.logger=INFO,console

注意 –name 选项指定的名字必须要和配置文件里面的agent名字一致才行,否则会提示找不到对应的配置。

启动以后使用 telnet 127.0.0.1 4444 访问,然后输入文字flume就可以收集到数据。具体数据如下:

1
2
2018-05-18 17:01:21,693 Event: { headers:{} body: 68 65 6C 6C 6F 0D   hello. }              
2018-05-18 17:01:26,912 Event: { headers:{} body: 77 6F 72 6C 64 0D world. }

可以看到他每一条消息都是一个Event 也就是说在Flume中每一个Event都是一个基本的传送单元。

Event = header + body

3. 实战

1. 从文件中读取数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Name the components on this agent
a1.sources = r1
a1.sinks = k1
a1.channels = c1

# Describe/configure the source
a1.sources.r1.type = exec
a1.sources.r1.command = tail -F /root/data.log
a1.sources.r1.shell = /bin/bash -c

# Describe the sink
a1.sinks.k1.type = logger

# Use a channel which buffers events in memory
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100

# Bind the source and sink to the channel
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1

2. A机向B机传输采集的数据

首先配置A机 ,我们采用的是 exec 监控一个文件,然后使用 memory channel 输出到 avro ,所以有配置文件 exec-memcory-avro.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
exec-memcory-avro.sources = exec-source
exec-memcory-avro.sinks = avro-sink
exec-memcory-avro.channels = memory-channel

exec-memcory-avro.sources.exec-source.type = exec
exec-memcory-avro.sources.exec-source.command = tail -F /root/data.log
exec-memcory-avro.sources.exec-source.shell = /bin/bash -c

exec-memcory-avro.sinks.avro-sink.type = avro
exec-memcory-avro.sinks.avro-sink.hostname = master
exec-memcory-avro.sinks.avro-sink.port = 4444

exec-memcory-avro.channels.memory-channel.type = memory
exec-memcory-avro.channels.memory-channel.capacity = 1000
exec-memcory-avro.channels.memory-channel.transactionCapacity = 100


exec-memcory-avro.sources.exec-source.channels = memory-channel
exec-memcory-avro.sinks.avro-sink.channel = memory-channel

执行如下的命令可以启动,但是不要现在启动否则会报错

1
2
3
4
5
flume-ng agent \
--name exec-memcory-avro \
-c $FLUME_HOME/conf \
-f $FLUME_HOME/conf/exec-memcory-avro.conf \
-Dflume.root.logger=INFO,console

那么B机就需要使用avro source来接受了,然后使用memory做channel,最后使用logger做输出。建立配置文件avro-memory-logger.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
avro-memory-logger.sources = avro-source
avro-memory-logger.sinks = logger-sink
avro-memory-logger.channels = memory-channel

avro-memory-logger.sources.avro-source.type = avro
avro-memory-logger.sources.avro-source.bind = master
avro-memory-logger.sources.avro-source.port = 4444

avro-memory-logger.sinks.logger-sink.type = logger

avro-memory-logger.channels.memory-channel.type = memory
avro-memory-logger.channels.memory-channel.capacity = 1000
avro-memory-logger.channels.memory-channel.transactionCapacity = 100


avro-memory-logger.sources.avro-source.channels = memory-channel
avro-memory-logger.sinks.logger-sink.channel = memory-channel

启动

1
2
3
4
5
flume-ng agent \
--name avro-memory-logger \
-c $FLUME_HOME/conf \
-f $FLUME_HOME/conf/avro-memory-logger.conf \
-Dflume.root.logger=INFO,console

我们要先启动后面的那个,也就是B机,不然的话我们先启动A机就会报错。

Vim 使用技巧

1.x 删除后面的字符 X 删除前一个字符 删除3个字符就是3x
2.caw:改写单词
3.J:删除换行符,使下一行并上来。 nJ:连接连同本行的n行
4.u:撤销上一次操作 U:撤销当前行的所有修改
5.i 在光标前插入 I 在行首插入
6.a 在光标后插入 A 在行末插入
7.o:在当前行的下面另起一行,并变为插入模式 O:在当前行上面另起一行,变为插入模式
8.vim中Nyy可以复制光标后的N行。有时我们不容易得出行数,这时可以用做标记的方法来制定复制范围 1. 在开始行上输入ma作一个标记a

  1. 移动到结束行,输入y’a会复制当前行到标记a之间的文本。d’a会删除。
    9.将光标放在 {或者( 处,然后输入v%就可以把大括号中内容选定
    10.想删除到“(”为止,则输入dt(就可以了,t(的作用是跳到下一个”(“前。
    11.%: 移动到与制匹配的括号上去(),{},[],<>等
    12.’ 移动到上一次的修改行
    13.# 到与当前单词相同的上一个单词上, * 到与当前单词相同的下一个单词上
    14.如果你要重复键入一个短语或一个句子, 也有一种快捷的方法。Vim有一种记录宏的机制。你键入”qa”开始把一段宏记录入寄存器变量a'中。 按下来你可以象平常一样键入你要的操作, 只是这些操作都会被Vim记录进它命名为a’的宏中, 再次再下”q”键, 就结束了宏`a’的录制。
    当你要重复执行你刚才记录的那些操作时只要使用”@a”命令。共有26个可用的寄存器供你记录宏。 使用宏你可以重复多个不同的操作。
    而不仅仅是插入文本了。如果你要进行某种重复的操作, 记着要用这一招呀。
    15.b、3b、w、3w:向前\后移动几个单词,标点也算一个单词。相应的大写状态为不含标点,即只把空格和换行符作为单词间隔符。
    16.$:移动到行尾 3$:移动到3行后的行尾 ^:移动到行首,0也是 +:移到下一行的行首 -: 移到上一行的行首
    17.33G:跳转到33行 此时按``可以返回到原来行 gg:文件头 G: 文件尾
  2. :set nu 设置行号
    19.ctrl+b\f 向上\下滚动一屏  这个比较实用,记住。
    20.zz:将当前行滚动于屏幕中间,方便查看上下文 zt置顶,zb置尾
    21./string 查找string,回车后,按n键可以跳到下一个,N上一个,另外按/键后,按上下键可以找到以前查找的记录,同样的 :也有记录
    ?/string 同上,默认向上查找
    22.:set ignorecase 大小写无关 :set noignorecase 大小写敏感
    23.>> 向右移动本行一段距离 << 向左移动本行一段距离 3<< 把下面3行(包括本行),向左移动一段距离 :20,30>> 把20行到30行向右移动一段距离
    24.:%s/str1/str2/g 替换每一行的 str1为 str2
    :10,20s/str1/str2/g 替换从行10到行20之间的 str1为 str2
    :10,$s/str1/str2/g 替换从行10到最后一行之间的 str1为 str2
    :s/str1/str2/g 替换当前行的 str1为 str2
    25.:10,$ w test2.cpp 取行10到最后一行内容,保存到test2.cpp

26.:r class/User.hpp 读取文件中的内容,插入到当前行的后面
27.dw:删除一个单词(光标后部分) 不如:daw实用
28.d4w:删除4个单词    d$:删除当前光标到行尾 
29.d换成c效果是一样的,只是操作完会变成insert模式
30.dnj: 向下删除n行 dnk: 向上删除n行 dn删除本行
31.D:相当于d$  C:相当于c$
32.r:替换当前字符,但不会进入insert模式 
33.yaw: 复制一个单词,光标在单词任意位置 ynw: 复制N个单词 ynj: 向下复制n行 ynk: 向上复制n行
34.ci’、ci”、ci(、ci[、ci{、ci< - 分别更改这些配对标点符号中的文本内容
di’、di”、di(或dib、di[、di{或diB、di< - 分别删除这些配对标点符号中的文本内容
yi’、yi”、yi(、yi[、yi{、yi< - 分别复制这些配对标点符号中的文本内容
vi’、vi”、vi(、vi[、vi{、vi< - 分别选中这些配对标点符号中的文本内容.

  • % 快速定位到本行的括号

SparkStreaming 入门

1. 基本原理

其实在 SparkStreaming 中和之前的Core不同的就是他会把任务分成批次的进行处理,也就是我们需要设置间隔多久计算一次。

我们从网络,文件系统,Kafka 等等数据源产生的地方获取数据,然后SparkStreaming放到内存中,接着进行对数据进行计算,获取结果。

Read More