一、 缓存
1)JSR107
Java Caching界说了5个焦点接口,分别是:
界说了创建、设置、获取、管理和控制多个CacheManager。一个应用可以在运行期访问多个CachingProvider。
界说了创建、设置、获取、管理和控制多个唯一定名的Cache,这些Cache存在于CacheManager的上下文中。一个CacheManager仅被一个CachingProvider所拥有。
是一个类似Map的数据结构并暂时存储以Key为索引的值。一个Cache仅被一个CacheManager所拥有。
是一个存储在Cache中的key-value对。
每一个存储在Cache中的条目有一个界说的有效期。一旦高出这个时间,条目为逾期的状态。一旦逾期,条目将不可访问、更新和删除。缓存有效期可以通过ExpiryPolicy设置。
2)Spring缓存抽象
Spring从3.1开始界说了
org.springframework.cache.Cache和org.springframework.cache.CacheManager接口来同一差别的缓存技能,并支持使用JCache(JSR-107)注解简化我们开辟。
- Cache接口为缓存的组件规范界说,包罗缓存的各种利用聚集
- Cache接口下Spring提供了各种xxxCache的实现;如RedisCache,EhCacheCache ,ConcurrentMapCache等
- 每次调用必要缓存功能的方法时,Spring会查抄指定参数的指定的目的方法是否已经被调用过,如果有就直接从缓存中获取方法调用后的结果,如果没有就调用方法并缓存结果后返回给用户。下次调用直接从缓存中获取。
- 使用Spring缓存抽象时我们必要关注以下两点:
- 确定方法必要被缓存以及他们的缓存计谋
- 从缓存中读取之前缓存存储的数据
3)几个告急缓存注解
4)缓存使用
- 引入spring-boot-starter-cache模块
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId></dependency>复制代码
@MapperScan("cbuc.life.cache.mapper")@SpringBootApplication@EnableCachingpublic class Springboot01CacheApplication { public static void main(String[] args) { SpringApplication.run(Springboot01CacheApplication.class, args); }}复制代码
- @Cacheable
- @CacheEvict
- @CachePut
将数据生存在ConcurrentMap<Object, Object>中
开辟中使用缓存中心件:redis、memcached、ehcache
5)几大属性
- cacheNames/value: 指定缓存组件的名字,将方法的返回结果放在哪个缓存中,是数组的方式,可以指定多个缓存
- key: 缓存数据使用的key,可以用它来指定。默认是使用方法参数的值
- keyGenerator: key的天生器,可以本身指定key的天生器的组件id
- cacheManager:指定缓存管理器,大概 cacheResolver 指定获取剖析器
- condition:指定符合条件的环境下才缓存
- unless:否定缓存,当 unless 指定的条件为true,方法的返回值就不会被缓存
- sync:是否使用异步模式
2)
3)
4)
6)整合redis
- 引入spring-boot-starter-data-redis
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId></dependency>复制代码2.application.yml设置 redis 连接地点
spring.redis.host=118.24.44.169复制代码3.使用ReditTemplate利用redis
4.设置缓存
5.自界说redisTemplate
6.将自界说的redisTemplate注册进RedisCacheManager
二、消息
*大多应用中,可通过消息服务中心件来提升体系异步通讯、扩展解耦本领 *
消息服务中两个告急概念:
- 消息署理(message broker)
- 目的地(destination)
当消息发送者发送消息以后,将由消息署理接受,消息署理包管消息转达到指定目的地。
消息队列告急有两种形式的目的地
- 队列(queue):点对点消息通讯(point-to-point)
- 主题(topic):发布(publish)/订阅(subscribe)消息通讯
点对点式
- 消息发送者发送消息,消息署理将其放入一个队列中,消息吸取者从队列中获取消息内容,消息读取后被移出队列
- 消息只有唯一的发送者和担当者,但并不是说只能有一个吸取者
发布订阅式
- 发送者(发布者)发送消息到主题,多个吸取者(订阅者)监听(订阅)这个主题,那么就会在消息到达时同时收到消息
JMS(Java Message Service)JAVA消息服务
- 基于JVM消息署理的规范。ActiveMQ、HornetMQ是JMS实现
AMQP(Advanced Message Queuing Protocol)
- 高级消息队列协议,也是一个消息署理的规范,兼容JMS
- RabbitMQ是AMQP的实现
Spring支持
- spring-jms提供了对JMS的支持
- spring-rabbit提供了对AMQP的支持
- 必要ConnectionFactory的实现来连接消息署理
- 提供JmsTemplate、RabbitTemplate来发送消息
- @JmsListener(JMS)、@RabbitListener(AMQP)注解在方法上监听消息代剃头布的消息
- @EnableJms、@EnableRabbit开启支持
Spring Boot主动设置
- JmsAutoConfiguration
- RabbitAutoConfiguration
RabbitMQ
简介:
RabbitMQ是一个由erlang开辟的AMQP(Advanved Message Queue Protocol)的开源实现。
焦点概念:
- Message:
消息,消息是不具名的,它由消息头和消息体构成。消息体是不透明的,而消息头则由一系列的可选属性构成,这些属性包罗routing-key(路由键)、priority(相对于其他消息的优先权)、delivery-mode(指出该消息大概必要长期性存储)等。
- Publisher:
消息的生产者,也是一个向交换器发布消息的客户端应用步调。
- Consumer:
消息的消耗者,表现一个从消息队列中取得消息的客户端应用步调。
- Exchange:
交换器,用来吸取生产者发送的消息并将这些消息路由给服务器中的队列。差别范例的Exchange转发消息的计谋有所区别
- direct(默认)
- fanout
- topic
- headers
- Queue:
消息队列,用来生存消息直到发送给消耗者。它是消息的容器,也是消息的尽头。一个消息可投入一个或多个队列。消息一直在队列内里,期待消耗者连接到这个队列将其取走。
- Binding:
绑定,用于消息队列和交换器之间的关联。一个绑定就是基于路由键将交换器和消息队列连接起来的路由规则,所以可以将交换器明确成一个由绑定构成的路由表。Exchange 和Queue的绑定可以是多对多的关系。
- Connection:
网络连接,比如一个TCP连接。
- Channel:
信道,多路复用连接中的一条独立的双向数据流畅道。信道是创建在真实的TCP连接内的捏造连接,AMQP 下令都是通过信道发出去的,不管是发布消息、订阅队列还是吸取消息,这些动作都是通过信道完成。由于对于利用体系来说创建和烧毁 TCP 都好坏常昂贵的开销,所以引入了信道的概念,以复用一条 TCP 连接。
- Virtual Host:
捏造主机,表现一批交换器、消息队列和相关对象。捏造主机是共享类似的身份认证和加密环境的独立服务器域。每个 vhost 本质上就是一个 mini 版的 RabbitMQ 服务器,拥有本身的队列、交换器、绑定和权限机制。vhost 是 AMQP 概念的基础,必须在连接时指定,RabbitMQ 默认的 vhost 是 / 。
- Broker:
表现消息队列服务器实体
运行机制:
AMQP 中消息的路由过程和 Java 开辟者认识的 JMS 存在一些差别,AMQP 中增长了 Exchange 和Binding 的脚色。生产者把消息发布到 Exchange 上,消息最终到达队列并被消耗者吸取,而 Binding 决定交换器的消息应该发送到哪个队列。
Exchange分发消息时根据范例的差别分发计谋有区别,如今共四种范例:direct、fanout、topic、headers 。headers 匹配 AMQP 消息的* header 而不是路由键*, headers 交换器和 direct 交换器完全划一,但性能差很多,如今险些用不到了,所以直接看别的三种范例:
消息中的路由键(routing key)如果和 Binding 中的 binding key 划一, 交换器就将消息发到对应的队列中。路由键与队列名完全匹配,如果一个队列绑定到交换秘密求路由键为“dog”,则只转发 routing key 标志为“dog”的消息,不会转发“dog.puppy”,也不会转发“dog.guard”等等。它是完全匹配、单播的模式。
2.fanout
每个发到 fanout 范例交换器的消息都会分到所有绑定的队列上去。fanout 交换器不处置处罚路由键,只是简朴的将队列绑定到交换器上,每个发送到交换器的消息都会被转发到与该交换器绑定的所有队列上。很像子网广播,每台子网内的主机都得到了一份复制的消息。fanout 范例转发消息是最快的。
3.topic
topic 交换器通过模式匹配分配消息的路由键属性,将路由键和某个模式举行匹配,此时队列必要绑定到一个模式上。它将路由键和绑定键的字符串切分成单词,这些单词之间用点隔开。它同样也会识别两个通配符:符号“#”和符号“”。#匹配0个或多个单词,匹配一个单词。
整合RabbitMQ
- 引入 spring-boot-starter-amqp
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId></dependency>复制代码
spring.rabbitmq.host=118.24.44.169spring.rabbitmq.username=guestspring.rabbitmq.password=guest复制代码
示例:
@Configurationpublic class MyAMQPConfig { @Bean public MessageConverter messageConverter(){ return new Jackson2JsonMessageConverter(); }}复制代码
/** * 注入我们必要的两个bean */@AutowiredRabbitTemplate rabbitTemplate;@AutowiredAmqpAdmin amqpAdmin;复制代码
Service 中吸取消息示例
注意要在启动类中开启基于注解的RabbitMQ模式 :@EnableRabbit
三、检索
我们的应用常常必要添加检索功能,开源的 ElasticSearch是如今全文搜刮引擎的首选。他可以快速的存储、搜刮和分析海量数据。Spring Boot通过整合Spring Data ElasticSearch为我们提供了非常便捷的检索功能支持;
Elasticsearch是一个分布式搜刮服务,提供Restful API,底层基于Lucene,采取多shard(分片)的方式包管数据安全,而且提供主动resharding的功能,github等大型的站点也是采取了ElasticSearch作为其搜刮服务
概念
以 员工文档 的形式存储为例:一个文档代表一个员工数据。存储数据到 ElasticSearch 的举动叫做索引,但在索引一个文档之前,必要确定将文档存储在那里。
一个 ElasticSearch 集群可以 包罗多个 索引,相应的每个索引可以包罗多个 范例 。 这些差别的范例存储着多个 文档 ,每个文档又有 多个 属性 。
类似关系:
- 索引 ==== 数据库
- 范例 ==== 表
- 文档 ==== 表中的记载
- 属性 ==== 列
整合ElasticSearch
SpringBoot 默认支持两种技能来和 ES 交互
导入jest的工具包
<dependency> <groupId>io.searchbox</groupId> <artifactId>jest</artifactId> <version>5.3.3</version></dependency>复制代码
- 版本适配标题升级SpringBoot版本安装对应版本的ES
- 导入工具包
<!--SpringBoot默认使用SpringData ElasticSearch模块举行利用--><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId></dependency>复制代码
- 安装Spring Data 对应版本的ElasticSearch
- application.properties设置
spring.data.elasticsearch.cluster-name=elasticsearchspring.data.elasticsearch.cluster-nodes=118.24.44.169:9301复制代码
@Document(indexName = "cbuc",type = "book")public class Book { private Integer id; private String bookName; private String author; //省略 get/set方法}public class Article { @JestId private Integer id; private String author; private String title; private String content; //省略 get/set 方法}复制代码
- 编写 ElasticsearchRepository:
public interface BookRepository extends ElasticsearchRepository<Book,Integer> { //参照 https://docs.spring.io/spring-data/elasticsearch/docs/3.0.6.RELEASE/reference/html/ public List<Book> findByBookNameLike(String bookName);}复制代码
@AutowiredJestClient jestClient;@AutowiredBookRepository bookRepository;复制代码法1:
存入index:
Book book = new Book();book.setId(1);book.setBookName("西游记");book.setAuthor("吴承恩");bookRepository.index(book);复制代码取:
for (Book book : bookRepository.findByBookNameLike("游")) { System.out.println(book);}复制代码法2:
//给Es中索引(生存)一个文档:Article article = new Article();article.setId(1);article.setTitle("测试");article.setAuthor("cbuc");article.setContent("测试检索");//构建一个索引功能Index index = new Index.Builder(article).index("cbuc").type("news").build();//实行jestClient.execute(index);复制代码测试搜刮:
//查询表达式@Testpublic void search(){ //查询表达式 String json ="{\n" + " \"query\" : {\n" + " \"match\" : {\n" + " \"content\" : \"hello\"\n" + " }\n" + " }\n" + "}"; //更多利用: https://github.com/searchbox-io/Jest/tree/master/jest //构建搜刮功能 Search search = new Search.Builder(json).addIndex("cbuc").addType("news").build(); //实行 try { SearchResult result = jestClient.execute(search); System.out.println(result.getJsonString()); } catch (IOException e) { e.printStackTrace(); }}复制代码四、任务
异步任务
在Java应用中,绝大多数环境下都是通过同步的方式来实现交互处置处罚的。但是在处置处罚与第三方体系交互的时间,轻易造成相应迟缓的环境,之前大部门都是使用多线程来完成此类任务,实在,在Spring 3.x之后,就已经内置了@Async来美满办理这个标题。
两个注解:
使用:
@EnableAsync //开启异步注解功能@SpringBootApplicationpublic class Springboot04TaskApplication { public static void main(String[] args) { SpringApplication.run(Springboot04TaskApplication.class, args); }}复制代码2.Service:
@Servicepublic class AsyncService { //告诉Spring这是一个异步方法 @Async public void test(){ try { //当前线程就寝 3 秒页面也能实时相应 Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("处置处罚数据中..."); }}复制代码3.Controller:
@RestControllerpublic class AsyncController { @Autowired AsyncService asyncService; @GetMapping("/hello") public String hello(){ asyncService.test(); return "success"; }}复制代码定时任务
项目开辟中常常必要实行一些定时任务,比如必要在每天破晓时间,分析一次前一天的日志信息。Spring为我们提供了异步实行任务调理的方式,提供TaskExecutor、TaskScheduler接口。
两个注解:
- @EnableScheduling
- @Scheduled
cron表达式:
使用:
@EnableScheduling //开启基于注解的定时任务@SpringBootApplicationpublic class Springboot04TaskApplication { public static void main(String[] args) { SpringApplication.run(Springboot04TaskApplication.class, args); }}复制代码2.Service:
邮件任务
使用:
- 邮件发送必要引入spring-boot-starter-mail
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId></dependency>复制代码
- 界说MailProperties内容,设置在application.properties中
spring.mail.username=(发送人qq账号)spring.mail.password=(发送人qq暗码)spring.mail.host=smtp.qq.comspring.mail.properties.mail.smtp.ssl.enable=true复制代码3.主动装配JavaMailSender
五、分布式体系
单一应用架构
当网站流量很小时,只需一个应用,将所有功能都摆设在一起,以减少摆设节点和资本。此时,用于简化增编削查工作量的数据访问框架(ORM)是关键。
垂直应用架构
当访问量渐渐增大,单一应用增长呆板带来的加速度越来越小,将应用拆成互不干系的几个应用,以提升服从。此时,用于加速前端页面开辟的Web框架(MVC)是关键。
活动盘算架构
当服务越来越多,容量的评估,小服务资源的浪费等标题渐渐显现,此时需增长一个调理中心基于访问压力实时管理集群容量,进步集群使用率。此时,用于进步呆板使用率的资源调理和管理中心(SOA)是关键
分布式服务架构
当垂直应用越来越多,应用之间交互不可克制,将焦点业务抽取出来,作为独立的服务,渐渐形成稳固的服务中心,使前端应用能更快速的相应多变的市场需求。此时,用于进步业务复用及整合的分布式服务框架(RPC)是关键。
Zookeeper和Dubbo
ZooKeeper:
是一个分布式的,开放源码的分布式应用步调和谐服务。它是一个为分布式应用提供划一性服务的软件,提供的功能包罗:设置维护、域名服务、分布式同步、组服务等。
Dubbo:
是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(大概最大限度地松耦合)。从服务模子的角度来看,Dubbo采取的是一种非常简朴的模子,要么是提供方提供服务,要么是消耗方消耗服务,所以基于这一点可以抽象出服务提供方(Provider)和服务消耗方(Consumer)两个脚色。
使用:
- 安装zookeeper作为注册中心
- 编写服务提供者
引入dubbo和zkclient相关依靠
<dependency> <groupId>com.alibaba.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>0.1.0</version></dependency><!--引入zookeeper的客户端工具--><!-- https://mvnrepository.com/artifact/com.github.sgroschupf/zkclient --><dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>0.1</version></dependency>复制代码设置dubbo的扫描包和注册中心地点
dubbo.application.name=provider-ticket dubbo.registry.address=zookeeper://118.24.44.169:2181 dubbo.scan.base-packages=cbuc.life.ticket.service复制代码使用@Service发布服务
@Component @Service //将服务发布出去 注意注解 Service是dubbo包下的 public class TicketServiceImpl implements TicketService { @Override public String getTicket() { return "《我和我的故国》"; } }复制代码
引入dubbo和zkclient相关依靠
<dependency> <groupId>com.alibaba.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>0.1.0</version> </dependency> <!--引入zookeeper的客户端工具--> <!-- https://mvnrepository.com/artifact/com.github.sgroschupf/zkclient --> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>0.1</version> </dependency>复制代码引用服务
@Service public class UserService{ @Reference // 使用 Reference 引入服务 TicketService ticketService; public void hello(){ String ticket = ticketService.getTicket(); System.out.println("调用买票服务:"+ticket); } }复制代码Spring Boot和Spring Cloud
Spring Cloud是一个分布式的团体办理方案。Spring Cloud 为开辟者提供了在分布式体系(设置管理,服务发现,熔断,路由,微署理,控制总线,一次性token,全局锁,leader推举,分布式session,集群状态)中快速构建的工具,使用Spring Cloud的开辟者可以快速的启动服务或构建应用、同时可以或许快速和云平台资源举行对接。
SpringCloud分布式开辟五大常用组件:
- 服务发现 —— Netflix Eureka
- 客服端负载平衡 —— Netflix Ribbon
- 断路器 —— Netflix Hystrix
- 服务网关 —— Netflix Zuul
- 分布式设置 —— Spring Cloud Config
使用:
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Edgware.SR3</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies></dependencyManagement>复制代码
server: port: 8761eureka: instance: hostname: eureka-server # eureka实例的主机名 client: register-with-eureka: false #不把本身注册到eureka上 fetch-registry: false #不从eureka上来获取服务的注册信息 service-url: defaultZone: http://localhost:8761/eureka/复制代码
@EnableEurekaServer @SpringBootApplicationpublic class EurekaServerApplication { public static void main(String[] args) { SpringApplication.run(EurekaServerApplication.class, args); }}复制代码
引入依靠
设置application
启动类
service
controller
引入依靠
设置application
启动类
controller (通过使用RestTemplate调用服务)
|