springCloud组件基本设置以及案例

SSM

dao层/service层/controller spring容器贯穿始终,所有的Bean,配置文件直接面向spring容器

 

业务层接口+实现类

传统ssm中: 业务层接口在Controller层@Autowired注入生成代理类对象

dubbo分布式中: 业务层接口注册到zookeeper 在Controller中@Reference注入 生成RPC代理类对象

 

dao层接口+mapper.xml(接口映射文件)

传统ssm中: dao层接口在业务层@Autowired注入生成代理类对象.

注意: 要求dao接口与映射文件mapper.xml同路径同名且反斜杠

springBoot中: dao层接口在业务层@Autowired注入, dao接口需要添加注解@Mapper / 启动类添加注解 @MapperScan("xx.xxx")接口包扫描

注意: 只要求接口与映射文件mapper.xml同名, 在yml中已经指定了路径

springBoot管理SSM

SpringBoot与MyBatis

步骤;

1 依赖启动器

MyBatis-spring-boot-starter

2 application.yml参数配置

JDBC连接池参数:

 @ConfigurationProperties(prefix = "spring.datasource")
 public class DataSourceProperties implements BeanClassLoaderAware, InitializingBean{
  private String driverClassName;
  private String url;
  private String username;
  private String password;}

Mybatis参数:

 # 数据库链接信息
      spring:
        datasource:
          driver-class-name: com.mysql.jdbc.Driver
          url: jdbc:mysql://127.0.0.1:3306/saas-export
          username: root
          password: root
 
       # Mybatis配置
 
      mybatis:
        type-aliases-package: com.meidi.demo   # 类型别名包扫描
        mapper-locations:
        - classpath:mappers/*.xml   # 接口映射文件路径
        configuration:
          map-underscore-to-camel-case: true   # 开启驼峰映射
 
      server:
        port: 8080
 @ConfigurationProperties(prefix = "mybatis")
 public class MybatisProperties {
     public static final String MYBATIS_PREFIX = "mybatis";
     private static final ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
     private String configLocation;
     private String[] mapperLocations;    //接口映射文件路径(mapper.xml) - classpath:UserMapper.xml
     private String typeAliasesPackage;   //类型别名包扫描
     private Class<?> typeAliasesSuperType;  
     private String typeHandlersPackage;
     private boolean checkConfigLocation = false;
     private ExecutorType executorType;
     private Class<? extends LanguageDriver> defaultScriptingLanguageDriver;
     private Properties configurationProperties;

3 逆向工程生成3大件

4 dao接口类添加@Mapper 或者 启动类添加@MapperScan("cn.it.mapper") 接口包扫描

业务层@Autowired注入接口代理对象

5 编写mapper.xml接口映射文件,与接口同名 (因为在yml中有指定了路径,所以不需要像SSM一样与接口同路 径并且反斜杠)

 

SpringBoot与SpringMVC

步骤:

1 依赖启动器

 spring-boot-starter-web

2 编写@Controller

SpringBoot与日志控制

日志输出原理:

debug级别: 输出debug / info / warn /error日志信息

info级别: 输出info / warn / error日志信息

warn级别: 输出warn / error日志信息

error级别: 输出error日志信息

步骤

1 添加lombok插件和依赖

2 application.yml配置

         # 配置日志
      logging:
        level:
          cn.it.midea: debug   # 添加的路径使用debug级别的日志

3 添加日志注解@Slf4j自动生成log对象

 @RestController
 @Slf4j
 public class SpringController {
 
     @GetMapping("list")
     public String lisst(){
         //yml配置的debug级别可以输出debug/info/warn/error.日志
         log.debug("===== debug =====");
         log.info("===== debug =====");
         log.warn("===== warn =====");
         log.error("===== error =====");
         return "测试ok";
    }
 }

SpringBoot与拦截器

spring2.0 : 自定义拦截器 + xml配置文件

springBoot : 自定义拦截器 + 配置类

步骤:

1 自定义拦截器 实现接口HandlerInterceptor重写3大方法

 
 public class loginInterceptot implements HandlerInterceptor {
 
     //前置拦截 进入Controller前 返回值 : true放行 / false拦截
     @Override
     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
         System.out.println("前置拦截");
         return true;
    }
     //后置拦截 从Controller出来之后
     @Override
     public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
         System.out.println("后置拦截");
    }
     //最终拦截   试图渲染完成之后
     @Override
     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
         System.out.println("最终拦截");
    }
 }

 

2 编写配置类实现WebMvcConfigurer接口 (记得添加@Configuration配置类注解)

 

 

 

springBoot管理分布式

 

springBoot管理微服务

微服务 = springBoot + 微服务组件

RestTemplate

spring-web自带了一个模板工具类RestTemplate实现原始的HTTP远程调用

步骤:

1 在启动类创建RestTemplate添加到spring容器

2 在测试类中@Autowired注入RestTemplate对象

3 <T> RestTemplate . getForObject("url", <T>.class)

<T> RestTemplate . postForObject("url", null, <T>.class)

用法:

1 RestTemplate+DiscoveryClient可以调用微服务Feign接口 (DiscoveryClient可以获取host/post)

详细 见: DiscoveryClient--API

2 RestTemplate直接调用Controller

 

案例: 1 简单的RestTemplate调用

 

2 springBoot下服务提供 ,服务消费

SpringBootAndRestTemplate

Feign

Feign封装了HTTP客户端(RestTemplate)到spring容器, 直接注入接口完成springCloud的服务远程调用

内部集成了Ribbon负载均衡(同一个服务ID,多个实例进行轮询)还进行了增强.(默认开启)

内部集成了Hystrix熔断 (默认关闭状态)

 

步骤:

1 添加组件依赖

 spring-cloud-starter-openfeign

2 在启动类开启Feign客户端@EnableFeignClients

3 编写微服务接口 模拟出应用名: service-name微服务调用 http://service-name/user/6

 @FeignClient("service-name")
 public interface GetFeignClient{
     
     @GetMapping("user/{id}")
     public User findById(@PathVariable("id")Integer id);  //根据id查询的一个业务
 }

4 在微服务调用处@Autowired注入接口服务, 自动生成接口代理类对象.

 

Feign对负载均衡进行了增强 --- 重试机制 (轮询到一个失效服务时会自动重试其他服务)

Feign默认关闭Hystrix熔断,(因为重试机制 不知道何时才能获取到服务)开启后提供降级策略. 降级方法一般在GetWay中处理

 

 

Eureka

非集群注册中心

步骤:

1 导入Eureka组件 spring-cloud-starter-netflix-eureka-server

2 配置注册中心application.yml

 server:
  port: 8761 # 应用端口号(默认8761)
 
 spring:
  application:
    name: Eureka-Registry # 应用名称
 
 eureka:
  client:
    # 点开源码 service-url是一个map集合,键值对代码在源码中有提示
    service-url:
      # 如果eureka高可用(集群),配置对方服务地址 如果不是集群则配置自己的地址
      defaultZone: http://localhost:8761/eureka
    fetch-registry: false #是否拉取其他注册服务(默认true)
    register-with-eureka: true #是否将当前应用注册到Eureka(默认true)

3 启动类开启Eureka组件@EnableEurekaServer

案例: SpringCloudAndEureka

 

客户端(服务提供者)

步骤;

1 导入Eureka组件 spring-cloud-starter-netflix-eureka-client

2 启动类开启Eurka客户端 @EnableDiscoveryClient

3 配置application.yml

 server:
  port: 8001
 
 spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/springboot-db
    username: root
    password: root
  application:
    name: provider-8001 #应用名称
 
 mybatis:
  mapper-locations: mapper/UserMapper.xml #指定接口映射文件地址
  type-aliases-package: cn.it.midea.dao.pojo.User #实体类别名包扫描
 
 eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka # 指定Eureka注册中心地址

案例: SpringCloudAndEureka 使用的RestTemplate方法调用微服务

客户端(服务消费者)

步骤:

1 添加组件 spring-cloud-starter-netflix-eureka-client

2 启动类开启Eureka客户端 @EnableDiscoveryClient

3 配置application.yml

 server:
  port: 8080
 
 spring:
  application:
    name: consumer-8080 #应用名称
 
 eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka #指定Eureka注册中心地址

案例: SpringCloudAndEureka 使用的RestTemplate方法调用微服务

集群

注册中心集群:

核心: 集群ID相同且互相注册 (ID: spring.application.name)

步骤:

1 添加Eureka组件 spring-cloud-starter-netfilx-eureka-server

2 启动类开启Eureka @EnableEurekaServer

3 application.yml配置

 server:
  port: 8761 # 应用端口号(默认8761)
 
 spring:
  application:
    name: Eureka-Registry # 集群中应用名称相同
 
 eureka:
  client:
    service-url:
      # url地址互相注册
      defaultZone: http://localhost:8762/eureka,http://localhost:8763/eureka
    fetch-registry: true #是否拉取其他注册服务(默认true,可以忽略不写)
    register-with-eureka: true #是否将当前应用注册到Eureka(默认true,可以忽略不写)

案例: SpringCloudAndEurekaColony 通过Http客户端RestTemplate远程调用,没有经过Eureka

服务提供者集群

核心: 集群服务ID相同,并注册到注册中心集群的多个url中

步骤

1 添加组件 spring-cloud-starter-netflix-client

2 启动类开启客户端@EnabeDiscovertClient

3 application.yml

 server:
  port: 8002
 
 spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/springboot-db
    username: root
    password: root
  application:
    name: provider #多个提供者应用名称一致
 
 mybatis:
  mapper-locations: mapper/UserMapper.xml #指定接口映射文件地址
  type-aliases-package: cn.it.midea.dao.pojo.User #实体类别名包扫描
 
 eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka,
 http://localhost:8762/eureka,http://localhost:8763/eureka   # 注册到集群中心的多个地址

案例: SpringCloudAndEurekaColony 通过Http客户端RestTemplate远程调用,没有经过Eureka

 

 

DiscoveryClient--API

来源 : org.springframework.cloud.client.discovery.DiscoveryClient

注解@EnableDiscoveryClient友情提供

作用: 协助RestTemplate 动态获取微服务URL

Controller--(RestTemplate+DiscoveryClient)-->微服务--(RestTemplate+DiscoveryClient)-->其他微服务

         // 获取服务ID的所有实例的集合  实例可以有多个(相同的服务ID)以实现负载均衡  
         // serviceId就是yml中的spring.application.name: serviceId (注意方法中参数小写)
         List<ServiceInstance> instances = discoveryClient.getInstances("provider-8001");
 
         //从集合中获取第一个服务实例
         ServiceInstance serviceInstance = instances.get(0);
 
         //通过实例获取该实例的url的host port:
         String host = serviceInstance.getHost();
         int port = serviceInstance.getPort();
 
         //再拼接上提供者的路径得到url
         String url="http://"+ host +":"+ port +"provider/user/"+id;
 
         return restTemplater.getForObject(url,User.class);
 

案例: SpringCloudAndEureka 使用的RestTemplate方法调用微服务

 

Eureka高级

以下案例出现在 SpringCloudAndEurekaColony项目中

服务端高级

服务下线

给注册中心发送Rest请求,通知服务下线

失效剔除

既没有定时续约发送心跳,也没有发送下线请求, 但是服务失效. 服务端会默认90秒后失效剔除

每隔60秒扫描一次, 超过90秒没有续约的失效服务剔除

 eureka:
  server:
    eviction-interval-timer-in-ms: 900000   # 多久剔除,单位ms

 

自我保护

既没有定时续约发送心跳,也没有发送下线请求, 但是服务失效. 但是和失效剔除不同的是Eureka会统计服 务实例最近5main失效的比例是否在85%以内. 这段时间不会剔除任何服务,等待服务重新上线. 防止大 面积续约失败

 eureka:
  server:
    enable-self-preservation: true # 开启自我保护(默认)

 

客户端高级(提供者)

指定服务提供者地址IP

Eureka会判断服务是否注册(eureka.client.register-with-eureka: true默认), 接着提供者会向 EurekaServer发送Rest信息(包含服务元数据信息), Eureka会将服务提供者信息保存进双层map集合

     Map<String, Map<String, Object>>

外层map : String-->服务ID (spring.application.name)

内层map : String-->服务实例ID ( localhost : 服务ID : post) localhost:user-service:9001

Object-->服务实例集群 (再嵌套集群中其他实例)

修改内层map中的localhost改用IP代替, 方便指名服务所在服务器地址

 eureka:
   instance:
     ip-address: 127.0.0.1
     prefer-ip-address: true  # 使ip地址生效

控制台效果 : url = http://127.0.0.1:8001provider/user/2

服务续约

服务提供者定时向服务注册中心发送心跳, 默认30秒发送一次心跳. 服务失效默认90秒.

 eureka:
   instance:
     lease-renewal-interval-in-seconds: 30 # 服务续约(心跳)间隔时间
     lease-expiration-duration-in-seconds: 90 # 服务失效时间(默认超过90秒的注册中心会失效剔除)

 

客户端高级(消费者)

定时拉取服务列表

服务消费者启动时判断 fetch-registry 是否为true. 如果是则会将注册中心服务列表缓存到消费者 (即 使关闭注册中心依然能获取服务的原因), 并且默认每隔30秒重新拉取一次

 eureka:
   client:
     fetch-registry: true  # 是否拉取服务列表  默认true  
     registry-fetch-interval-seconds: 30 # 服务消费者每隔30秒从注册中心拉取一次服务列表  默认30秒

 

 

Ribbon

步骤:

1 服务消费者添加Ribbon组件 Ribbon集成在了Eureka组件中

2 RestTemplate配置类添加注解@LoadBalanced

3 application.yml

 

 

 

 

posted @ 2021-01-07 00:13  __Ethan  阅读(221)  评论(0编辑  收藏  举报