SpirngCloud基础

SpringCloud

1.认识微服务:

微服务是一种经历良好设计的分布式架构方案:

服务器架构特征:

单一责任:每个服务按照业务进行颗粒划分;

面向服务:对外提供接口,服务之间通过轻量级机制 通过REST

技术独立:可以使用不同语言,不同的技术开发

数据独立:拥有独立的数据库,可以使用不同的数据存储技术

部署独立:服务可以独立部署,独立扩展,服务之间不影响

微服务技术对比:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

组件:

注册发现:Eureka Nacos Consul

统一配置:SpringConfig Nacos

远程服务调用:OpenFeign Dubbo

服务链路监控:Zipkin Sleuth

统一网关路由:SpringCloudGetWay Zuul

流控 降级 保护:Hystix Sentinel

2.Eureka

创建Eureka服务端
 <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>2023.0.1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
   <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            <version>4.1.1</version>
        </dependency>
//开启注解
@EnableEurekaServer

配置

server:
  port: 10086
spring:
  application:
    name: EurekaServer
eureka:
  client:
    service-url:
      defaultZone: http://localhost:10086/eureka/

其他服务模块注册
	<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>2023.0.1</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>

客服端

<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
		</dependency>
spring:
  application:
    name: userService
  datasource:
    url: jdbc:mysql://localhost:3306/cloud_user?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
    username: root
    password: 303030
    driver-class-name: com.mysql.cj.jdbc.Driver
mybatis-plus:
  configuration:
    map-underscore-to-camel-case: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  mapper-locations: classpath:mapper/*.xml
server:
  port: 8081

eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka/

    @GetMapping("/order/{orderId}")
    public Order queryOrderByUserId(@PathVariable("orderId") Long orderId) {
        // 根据id查询订单并返回
        Order order = orderService.getById(orderId);
        //这里主机地址直接改为服务器名
        String url="http://userService/user/"+order.getUserId();
        User user = restTemplate.getForObject(url, User.class);
        order.setUser(user);
        return order;
    }
}

3.LoadBalancer负载均衡

主要功能客户端的负载均衡算法和服务调用

导入依赖

<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

在RestTemplate组件上添加@LoadBalanced注解

   @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

原理:

订单服务首先发送请求给loadBalancer负载均衡组件,在loadBalancer中,有一个拦截器LoadBalancerInterceptor,会拦截RestTemplate发送的HTTP请求,loadBalancer首先根据地址中的服务名从Eureka注册中心拉去服务器列表,然后使用一定的算法(轮询和随机)从列表中选择一个地址进行远程调用。

算法

可以看到在该组件中默认采用的是轮询算法(RoundRobinLoadBalancer),在loadBalancer中,提供了两种算法:RoundRobinLoadBalancer(轮询)和RandomLoadBalancer(随机)

切换负载均衡模式

@Configuration
public class CustomLoadBalancerConfiguration {
    @Bean
    ReactorLoadBalancer<ServiceInstance> loadBalancer(Environment environment,
                                                      LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);

        //返回随机轮询负载均衡方式
        return new RandomLoadBalancer(loadBalancerClientFactory.
                getLazyProvider(name, ServiceInstanceListSupplier.class),
                name);
    }

}

开启定义的负载均衡模式

@SpringBootApplication
@LoadBalancerClients(
        {@LoadBalancerClient(name = "userService",configuration = CustomLoadBalancerConfiguration.class)

        }
)
public class OrderServiceApplication {

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

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

4.Feign远程调用

使用RestTemplate方式调用存在问题

可读性差 URL维护麻烦传递参数不方便

代码不够优雅

Feign是一个声明式的Web服务客户端,它让编写Web服务客户端变得更加简单。我们不用再写一堆复杂的代码来处理HTTP请求,只需要通过简单的接口和注解,就能完成服务间的调用。

依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

开启注解

@EnableFeignClients

声明

@FeignClient(name = "userService")
public interface UserServiceClient {

 //通过@GetMapping注解定义调用的具体路径
    
    @GetMapping("/user/{id}")
    User getUserById(@PathVariable Long id);
}

使用

   @GetMapping("/order/{orderId}")
    public Order queryOrderByUserId(@PathVariable("orderId") Long orderId) {
        // 根据id查询订单并返回
        Order order = orderService.getById(orderId);
        //这里主机地址直接改为服务器名
        // String url="http://userService/user/"+order.getUserId();
        // User user = restTemplate.getForObject(url, User.class);
        User user = userServiceClient.getUserById(order.getUserId());
        order.setUser(user);
        return order;
    }

日志配置查看每次远程调用日志

  1. 首先在application.yml配置日志记录器级别(SpringBoot默认使用的是logback日志框架)
logging:
  level:
    com.cg.service.UserServiceClient: DEBUG

2.修改Feign组件中的日志级别,不同的级别记录的日志内容不同

  • NONE ,不记录(默认)。

  • BASIC ,仅记录请求方法和URL以及响应状态码和执行时间。

  • HEADERS ,记录基本信息以及请求和响应标头。

  • FULL ,记录请求和响应的标头、正文和元数据。

    @Configuration
    public class FeignConfig {
        @Bean
        Logger.Level feignLoggerLevel() {
            // 设置日志级别为FULL,记录请求和响应的头信息、正文和元数据
            return Logger.Level.FULL;
        }
    }
    
    

饥饿模式

通过接口调用,发现第一次请求服务的耗时很长(80ms左右),后面再请求只需要很短的时间(10ms左右),这是因为LoadBalancer组件默认采用懒加载,即第一次访问去创建服务实例(userservice),并且,可以通过配置饥饿加载让SpringBoot启动的时候就创建服务实例。

spring:
  cloud:
    loadbalancer:
      eager-load:
        clients: userservice

5.服务网关

在Gateway服务网关中提供了两大功能:

  1. 路由转发:通过配置网关路由,将外界请求转发到微服务中。
  2. 过滤器:通过配置过滤器可以过滤用户的请求和相应,实现身份认证、权限校验和限流等功能。

路由转发:

创建一个新的模块

1.依赖

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>2023.0.1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--eureka客户端 同样需要注册到eureka--> 
<dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2.配置
eureka:
  client:
    service-url:
      defaultZone: http://localhost:10086/eureka/

server:
  port: 80
spring:
  application:
    name: gateway
  cloud:
    ##配置路由规则
    gateway:
      routes:
        - id: userService # 路由id,自定义,只要唯一即可
          uri: lb://userService # 路由的目标地址,lb前缀表示从注册中心获取服务实例,lb后接服务注册中心注册的服务名称
          predicates: ##路由断言,判断请求是否符合路由规则
            - Path=/user/** # 定义路由路径匹配规则,只要以/user/开头就符合要求
        - id: orderService
          uri: lb://orderService
          predicates:
            - Path=/order/**

3.使用

在浏览器输入localhost/user/101 自动找到orderServer下的接口

GateWay过滤器 GatewayFilter

是网关中一种过滤器 可以对进入网关的请求 和服务器返回响应处理

提供了31种不同的路由过滤器工厂

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

spring:
  cloud:
    gateway:
      #配置路由规则
      routes:
        - id: userservice # 路由id,自定义,只要唯一即可
          uri: lb://userservice # 路由的目标地址,lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,判断请求是否符合路由规则
            - Path=/user/** # 定义路由路径匹配规则,只要以/user/开头就符合要求
          #配置过滤器
          filters:
            # 拦截请求,为所有访问userservice服务的请求添加请求头(info:Call userservice successful)
            - AddRequestHeader=info,Call userservice successful
        - id: orderservice
          uri: lb://orderservice
          predicates:
            - Path=/order/**

Gateway跨域问题

只是浏览器策略

spring:
  cloud:
    gateway:
      globalcors: # 全局的跨域处理
        corsConfigurations:
          '[/**]':
            allowedOrigins: # 允许哪些网站的跨域请求 
              - "http://127.0.0.1:8848"
              - "http://www.xxx.com"
            allowedMethods: # 允许的跨域ajax的请求方式
              - "GET"
              - "POST"
              - "DELETE"
              - "PUT"
            allowedHeaders: "*" # 允许在请求中携带的头信息
            allowCredentials: true # 是否允许携带cookie
            maxAge: 360000 # 这次跨域检测的有效期

父子工程

在父工程中只保留pom.xml文件,因为父工程只是作为项目聚合和依赖传递使用,不会产生业务数据以及相关配置

修改 Parent 项目 Pom.xml 的 packaging 标签打包方式为 pom

packaging 包含三个值 Jar、War、Pom,默认 Jar的方式

首先来解释下 packaging 为 Pom 的意思,宏观而言即没有代码需要测试或者编译,也没有资源需要处理

  • Jar: 内部调用或作为服务进行发布使用
  • War: 需要部署的项目
  • Pom: 寓意为一个父级项目,一般作为项目聚合和依赖传递使用
<!--packaging 标签打包方式为 pom,寓意为一个父级项目,一般作为项目聚合和依赖传递使用-->
    <packaging>pom</packaging>
    <modules>
        <module>user-service</module>
    </modules>

修改子项目

	<parent>
		<groupId>org.cg</groupId>
		<artifactId>springcloud-parent</artifactId>
		<version>1.0-SNAPSHOT</version>
	</parent>

首先来解释下 packaging 为 Pom 的意思,宏观而言即没有代码需要测试或者编译,也没有资源需要处理

  • Jar: 内部调用或作为服务进行发布使用
  • War: 需要部署的项目
  • Pom: 寓意为一个父级项目,一般作为项目聚合和依赖传递使用
<!--packaging 标签打包方式为 pom,寓意为一个父级项目,一般作为项目聚合和依赖传递使用-->
    <packaging>pom</packaging>
    <modules>
        <module>user-service</module>
    </modules>

修改子项目

	<parent>
		<groupId>org.cg</groupId>
		<artifactId>springcloud-parent</artifactId>
		<version>1.0-SNAPSHOT</version>
	</parent>
  • 7
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值