SpringBoot学习(五) 安全、分布式、热部署、监控管理

一.安全

1.Spring Security

简介
WebSecurityConfigurerAdapater 自定义security策略
AuthenticationManagerBuilder 自定义认证策略
@EnableWebSecrity 开启WebSecurity模式
Spring Security 的主要两个目标‘认证’Authentication,‘授权’Authorization
具体到Spring Security学习(一)查看

简单使用:
引入Spring Security

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

编写配置类


@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //指定请求规则
        http.authorizeRequests().antMatchers("/").permitAll()
                .antMatchers("/level1/**").hasRole("VIP1")
                .antMatchers("/level2/**").hasRole("VIP2");

        //开启自动配置的登录功能
        //访问 /login 来到登录界面
        //如果登录错误,重定向到 /login?error 表示登录失败
        //还可以有更多设置,如登录的用户名,密码
        http.formLogin();
 
         //开启注销,并且设置注销后返回的地址
        //访问/logout 表示用户注销,清空session
        //注销成功会返回 /logout:?logout 页面
        http.logout().logoutSuccessUrl("/");
        
        //开启 记住我 功能
        //登录成功后,将cookie发给浏览器保存,以后登录带上cookie,只要通过检查就可以免登陆
        //点击注销后,会销毁这个cookie
        http.rememberMe();
    }

    //定制认证规则
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("zhangsan").password("123456").roles("VIP1","VIP2")
                .and()
                .withUser("wangwu").password("123").roles("VIP1");
    }
}

配合thymeleaf模板在前端使用
导入maven依赖

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--isAuthenticated()是否认证过(登录过) -->
<div sec:authorize="!isAuthenticated()">
    <h1>请先登录!</h1>
</div>
<div sec:authorize="isAuthenticated()">
    <form th:action="@{/logout}">
        <input type="submit" value="注销"></input>
    </form>
</div>
<div sec:authorize="hasRole('VIP1')">
    <!--sec:authentication="name" 可以查看用户名 -->
    <span sec:authentication="name"></span>,你的VIP1用户,你的角色有:
    <!-- sec:authentication="principal.authorities" 可以查看权限角色 -->
    <span sec:authentication="principal.authorities"></span>
</div>

</body>
</html>

前面都是用的系统给我们的页面,现在我们想用自己的页面怎么办?

只需要在formLogin()后面添加loginPage 访问页面,usernameParameter,passwordParameter 用户名,密码的传递名字

 http.formLogin().loginPage("/userlogin").usernameParameter("user").passwordParameter("pwd");

这个时候,记住我 功能也需要自定义
添加rememberMeParameter参数,规定好名字,在前端使用name属性绑定记住我的选项

http.rememberMe().rememberMeParameter("remember");

二.分布式

1.zookeeper与Dubbo

zookeeper是注册中心,Dubbo是服务
简单使用:

Docker安装zookeeper

下载zookeeper

docker pull zookeeper

查看镜像id

docker images

运行容器

docker run --name zookeepper01 -p 2181:2181 --restart always -d ea93faa92337

开放对应端口的防火墙

firewall-cmd --zone=public --add-port=2181/tcp --permanent

开放后,需要重启一下防火墙

firewall-cmd --reload

如果你的阿里云,还需要去开放一下安全组

springboot简单整合

现在模拟一下购票流程,一个用户模块,一个购票模块。当用户调用购票功能时,会远程调用购票模块的购票功能。
在这里插入图片描述
两个模块都需要导入pom依赖

      <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>0.2.0</version>
        </dependency> 

生产者

购票模块的Service接口和实现类

public interface TickerService {
    void buy();
}

@Service
@Component
public class TickerServiceImpl implements TickerService{

    @Override
    public void buy() {
        System.out.println("买到票了");
    }
}

配置文件

spring.application.name=provider-ticket
#如果指定了spring应用名称,可以缺省dubbo的应用名称,这2个至少要配置1个。缺省dubbo的应用名称时默认值是spring的应用名称
#dubbo.application.name=user-service
dubbo.application.name=provider-ticket

#注册中心地址
dubbo.registry.address=zookeeper://xxx.xxx.xxx:2181
#端口号可以写在address中,也可以单独写。实质是从address中获取的port是null,后面设置的port覆盖了null
#dubbo.registry.port=2181

dubbo.protocol.name=dubbo
dubbo.protocol.port=20880

#指定注册到zk上超时时间,ms
dubbo.registry.timeout=10000


#指定实现服务(提供服务)的包
dubbo.scan.base-packages=com.pt.zoodubbo2.service

最后在启动类上加上@EnableDubbo,启动即可

@EnableDubbo
public class ZooDubbo2Application {

消费者

配置类

spring.application.name=provider-user
#如果指定了spring应用名称,可以缺省dubbo的应用名称,这2个至少要配置1个。缺省dubbo的应用名称时默认值是spring的应用名称
#dubbo.application.name=user-service
dubbo.application.name=provider-ticket


#注册中心地址
dubbo.registry.address=zookeeper://xxx.xxx.xxx:2181

创建一个TickerService接口,包路径和接口内容需要和生产者一致。

public interface TickerService {

    void buy();
}

消费者方法,只需要使用@Reference 就可以引入远程的TickerService

import com.alibaba.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Service;

@Service
public class UserService {
    @Reference
    TickerService tickerService;


    public void hello(){
     tickerService.buy();
    }
}

现在运行hello(),调用的tickerService.buy()就是远程的生产者的方法。

2.SpringCloud之eureka

先查看对应的springcloud版本,进行导入
官方springboot与springcloud对应Json数据

简介

SpringCloud是一个分布式整体解决方案,
springcloud分布式开发五大常用组件:
1.服务发现,Netflix Eureke
2.客服端负载均衡 Netflix Ribbon
3.断路器 Netflix Hystrix
4.服务网关 Netflix Zuul
5.分布式配置 Spring Cloud Config

简单使用

1.建立3个模块,一个euraka-server 注册中心, euraka-ticket 服务生产者 , euraka-consumer 服务消费者
在这里插入图片描述
2.配置注册中心

    <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>

配置文件application.yml

server:
  port: 8761
eureka:
  instance:
    hostname: eureka-server  #eureka实例的主机名
  client:
    register-with-eureka: false  #不把自己注册到eureka上
    fetch-registry: false #不从eureka上获取服务的注册信息
    service-url: http://localhost:8761/eureka/

启动类上添加@EnableEurekaServer,启动即可

@EnableEurekaServer
public class EurekaServerApplication {

3.服务生产者:
maven依赖

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>

yml配置

server:
  port: 8001
spring:
  application:
    name: provider-ticket

eureka:
  instance:
    prefer-ip-address: true #注册服务的时候,使用的ip地址
  client:
    service-url: http://localhost:8761/eureka/

运行后就放到注册中心了

4.服务消费者
导入依赖

   <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>

编写配置文件

spring:
  application:
    name: consumer-uer
server:
  port: 8200
eureka:
  instance:
    prefer-ip-address: true #注册服务的时候,使用的ip地址
  client:
    service-url: http://localhost:8761/eureka/

编写方法进行调用
启动类

@SpringBootApplication
@EnableDiscoveryClient //开启发现服务功能
public class EirakaConsumerApplication {

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

    @LoadBalanced //使用负载均衡机制
    @Bean
    public RestTemplate restTemplate(){

        return new RestTemplate();
    }

}

控制层方法;

@RestController
public class UserController {

    @Autowired
    RestTemplate restTemplate;

    @RequestMapping("/hello")
    public String Buy(){
        //第一个参数:http://服务生产者的spring.application.name/xxx
        // 第二个参数为返回值类型
        return restTemplate.getForObject("http://PROVIDER-TICKET/ticket",String.class);
    }
}

就可以实现了;
不过eureka现在已经停止更新了,所以估计以后也会用不着了

三.热部署

不重启应用的情况下,程序可以自动部署,叫做热部署

1.devtools

maven依赖

     <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>

导入后,修改了文件只需要编译一下,就能生效了

四.监控管理

准生产环境下的应用监控和管理功能

maven依赖

  <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
 </dependency>

监控管理端点:
在这里插入图片描述

配置文件中

## 启用端点 env
#management.endpoint.env.enabled=true
#
## 暴露端点 env 配置多个,隔开
#management.endpoints.web.exposure.include=env

#方式2:
#方式1中的暴露方式需要一个一个去开启需要暴露的端点,方式2直接开启和暴露所有端点
management.endpoints.web.exposure.include=*
#注意在使用Http访问端点时,需要加上默认/actuator 前缀

#开启shutdown,就可以远程使用post请求关闭应用
management.endpoint.shutdown.enabled=true

暴露端点后就可以访问上面的端点信息了

也可以修改这些端点的访问名字和访问路径

其中/health可以监听应用的健康状态,
其原理是使用了HealthIndicator
如配置了redis,会有一个RedisHealthIndicator,可以监听redis的监控状态。
如何自定义自己的HealthIndicator呢?
实现HealthIndicator 接口,并且放入容器即可。
使用/health查看的时候,会有My的信息

@Component
public class MyHealthIndicator implements HealthIndicator {

    @Override
    public Health health() {
        //自定义检查方法
        Health up = Health.up().build();//表示运行正常
        Health down = Health.down().build();//表示运行异常
        return up;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值