文章目录
十四、SpringBoot与分布式
分布式
Dubbo/Zookeeper
Dubbo的视频可以看这个视频,也是尚硅谷的雷神讲的(分布式目前还没学,打算看完springboot的视频后就去补Dubbo和springcloud)
Dubbo的流程图:
安装zookeeper
在linux的docker中拉取zookeeper的镜像(docker pull zookeeper
)
2181 跟客户端进行交互
2888 集群的端口
3888 全局的端口
运行zookeeper容器(docker run --name zk01 -p 2181:2181 --restart always -d zookeeper
)
创建工程
需要创建两个工程,一个是服务的提供者,一个是服务的消费者。
创建一个空工程
创建新模块
创建一个提供者(卖票的)
创建一个消费者(用户)
使用步骤
provider-ticket项目
-
在ticket包下新建service/TicketService接口
public interface TicketService { public String getTicket(); }
然后再在service包下新建一个TicketServiceImpl
@Component //加到容器中 public class TicketServiceImpl implements TicketService { @Override public String getTicket() { return "《HelloWorld》"; } }
-
在provider-ticket项目中引入依赖
<!-- Dubbo Spring Boot Starter --> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.7.6</version> </dependency>
-
引入curator依赖(zookeeper客户端框架,dubbo高版本好像是用这个的)
<!-- 对zookeeper的底层api的一些封装 --> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>4.2.0</version> </dependency> <!-- 封装了一些高级特性,如:Cache事件监听、选举、分布式锁、分布式Barrier --> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>4.2.0</version> </dependency>
-
在application.properties配置文件中配置dubbo
#起名(写项目名) dubbo.application.name=provider-ticket #注册中心的地址 dubbo.registry.address=zookeeper://10.211.55.17:2181 #想把项目下的哪些包发布出去 dubbo.scan.base-packages=com.angenin.ticket.service
-
在TicketServiceImpl类上加上dubbo的@Service注解
import org.apache.dubbo.config.annotation.Service; @Service //将服务发布出去
-
启动项目,并保持不关闭
consumer-user项目
- 引入依赖
<dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>4.2.0</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>4.2.0</version> </dependency> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.7.6</version> </dependency>
- 配置dubbo的注册中心地址
dubbo.application.name=consumer-user dubbo.registry.address=zookeeper://10.211.55.17:2181
- 在com.angenin包下新建ticket/service两层包,然后复制provider-ticket项目的TicketService放到service包下。(想使用provider-ticket项目的TicketServiceImpl的getTicket,需要在此项目下有和provider-ticket项目中的TicketService相同的包)
- 在user包下新建service/UserService
import com.angenin.ticket.service.TicketService; import org.apache.dubbo.config.annotation.Reference; import org.springframework.stereotype.Service; @Service //springboot中的@Service注解,添加到容器中 public class UserService { @Reference //远程引用(按照全类名进行匹配,所以才需要有相同的路径) TicketService ticketService; public void hello(){ String ticket = ticketService.getTicket(); System.out.println("买到票:" + ticket); } }
- 在测试类中测试
@Autowired UserService userService; @Test void contextLoads() { userService.hello(); }
- 运行测试方法(要注意的是provider-ticket项目需要一直运行着)
Spring Boot/Cloud
springcloud推荐看这个视频,是尚硅谷的阳哥讲的,而且是2020年3月发布的,最新版的H版&alibaba。
新建项目
创建一个空工程
新建模块(eureka-server注册中心)
使用步骤
新建模块(提供者)
新建模块(消费者)
eureka-server注册中心
- 在eureka-server项目的resources目录下新建application.yml配置文件,配置注册中心:
server: port: 8761 #服务器端口 eureka: instance: hostname: eureka-server #eureka实例的主机名 client: register-with-eureka: false #不把自己(eureka-server)注册到eureka上(不做高可用的情况下) fetch-registry: false #不从eureka上来获取服务的注册信息(因为本身就是注册中心,消费者就需要获取提供者的信息) service-url: defaultZone: http://localhost:8761/eureka/ #不指定默认为http://localhost:8761/eureka.client/
- 在主配置类上加上
@EnableEurekaServer
注解,启用这个注册中心。 - 启动eureka-server项目,访问
http://localhost:8761/
- 保持eureka-server运行着。
provider-ticket服务提供者
- 在provider-ticket项目providerticket包下新建service/TicketService:
在providerticket包下新建controller/TicketController:(因为没导入web模块,所以在这样要点击红灯泡导入)import org.springframework.stereotype.Service; @Service public class TicketService { public String getTicket(){ return "《HelloWorld》"; } }
@RestController public class TicketController { @Autowired TicketService ticketService; @GetMapping("/ticket") public String getTicket(){ return ticketService.getTicket(); } }
- 在resources目录下新建application.yml配置文件
server: port: 8001 spring: application: name: provider-ticket eureka: instance: prefer-ip-address: true #注册服务的时候使用服务的ip地址 client: service-url: defaultZone: http://localhost:8761/eureka/
- 启动项目
- 在浏览器输入
http://localhost:8001/ticket
在管理页面也可以看到注册并启动的PROVIDER-TICKET
并且我们可以把同个应用部署多个实例。 - 停止provider-ticket(eureka-server不要停)
- 设置同个项目可多次运行
- 启动项目,然后到application.yml中把端口修改为8002,再次启动项目
- 在浏览器分别输入:
http://localhost:8001/ticket
和http://localhost:8002/ticket
在管理页面可以看到同个项目的两个实例:
consumer-user服务消费者
- 在consumer-user项目的resources目录下新建application.yml
server: port: 8200 spring: application: name: consumer-user eureka: instance: prefer-ip-address: true #注册服务的时候使用服务的ip地址 client: service-url: defaultZone: http://localhost:8761/eureka/
- 给主配置类上添加
@EnableDiscoveryClient //开启发现服务功能 @SpringBootApplication public class ConsumerUserApplication { public static void main(String[] args) { SpringApplication.run(ConsumerUserApplication.class, args); } /** * 发送http请求,调用其他服务 * @return */ @LoadBalanced //使用负载均衡机制(只要加了这个注解才能使用服务名的调用) @Bean public RestTemplate restTemplate(){ return new RestTemplate(); } }
- 在consumeruser包下新建controller/UserController
@RestController //同样,添加一下web模块 public class UserController { @Autowired RestTemplate restTemplate; @GetMapping("/buy") public String buyTicket(String name){ //getForEntity获取数据,第一个参数为请求的地址,第二个参数为返回值的类型 //只有加入容器的RestTemplate上有@LoadBalanced注解,才能使用服务器名进行访问,不然只能用ip地址 String s = restTemplate.getForObject("http://PROVIDER-TICKET/ticket", String.class); return name + "购买了" + s; } }
- 启动项目(启动时不要选错了),在浏览器输入
http://localhost:8200/buy?name=张三
在管理页面可以看到注册的CONSUMER-USER。
通过RestTemplate对其他服务的发起请求,获取返回值,并且由于我们加了@LoadBalanced注解,实现了负载均衡,所以我们开启的两个服务提供者会轮流接收请求。
十五、SpringBoot与开发热部署
Developer Tools官方文档:https://docs.spring.io/spring-boot/docs/2.3.0.RELEASE/reference/html/using-spring-boot.html#using-boot-devtools
新建项目:
在developertools包下新建controller/HelloController
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello(){
return "<h1>hello</h1>";
}
}
启动项目,在浏览器输入http://localhost:8080
在不停下项目的情况下把请求地址/
改为/hello
,然后按Crtl+F9重新编译,再在浏览器输入http://localhost:8080/hello
,很显然是访问不了的。
项目停止运行。
使用Developer Tools
想使用热部署,需要引入Developer Tools依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
再次启动项目,在浏览器输入http://localhost:8080/hello
然后把请求地址改为/abc
,Crtl+F9重新编译,在浏览器输入http://localhost:8080/abc
十六、SpringBoot与监控管理
新建项目
启动项目,在浏览器输入http://localhost:8080/actuator
,可以看到,默认只暴露三个端点
在application.properties配置文件中加入
#开启所有端点
management.endpoints.web.exposure.include=*
#management.endpoints.web.exposure.exclude=env,beans #指定关闭哪个端点
#management.endpoint.端口名.enabled=true //开启指定端口
#management.endpoint.端口名.cache.time-to-live=10s #将指定端点的缓存的生存时间设置为10秒
如果是在application.yml中:(*要加上""双引号,避免歧义)
management:
endpoints:
web:
exposure:
include: "*"
重新运行项目,访问http://localhost:8080/actuator
具体介绍可以看官方文档:https://docs.spring.io/spring-boot/docs/2.3.0.RELEASE/reference/htmlsingle/#production-ready-enabling
自定义健康状态指示器
编写一个指示器,需要实现HealthIndicator接口,并且指示器的名字必须是xxxHealthIndicator,
@Component
public class MyAppHealthIndicator implements HealthIndicator {
@Override //返回健康状态
public Health health() {
//自定义的检查方法
return Health.up().build(); //代表健康
// return Health.down().withDetail("msg", "服务异常").build();
}
}
启动项目,在浏览器输入http://localhost:8080/actuator/health
看完视频后,发现还是有很多东西需要学习,继续努力。
学习视频(p31-p40):https://www.bilibili.com/video/BV1KW411F7oX?p=31