springcloud微服务组件简单介绍 和 快速应用

本文简要介绍了SpringCloud微服务架构的关键组件,包括SpringBoot项目的构建、Eureka注册中心、Ribbon负载均衡、Hystrix熔断器、Zuul网关和Feign客户端。详细阐述了各个组件的作用、应用场景以及如何在实际项目中搭建和配置。通过Eureka实现服务注册与发现,Ribbon实现负载均衡,Hystrix提供服务降级和熔断保护,Zuul作为API网关进行请求鉴权和路由转发,Feign简化REST服务调用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

内容介绍:简易版springcloud组件快速使用介绍

springcloud微服务架构快速应用

springcloud综述:使服务的提供者和消费者之间的交互变得便捷,方便相互之间的请求交互;使服务变得更可靠(高可用);使请求变得更随机(不需要写请求的具体地址,写个服务id即可)

总结起来就是6个字:便捷,可靠,高效

一、springboot-项目的构建

1.综述:

​ springboot的出现,改变了项目的管理和配置结构(只是配置少了),但我们业务核心代码的编写不会变。

2.核心理念:约定大于配置

​ 1.在springboot中提供了一个启动器,在其中写好了大量的默认配置。引入启动器的依赖,就可以实现这些 默认配置配置自动化 。具体配置在Mate-INF/spring.factory

​ 2.所谓约定:就是指公共的,大家都相同的东西,可以约定。但是个性化的东西还是必须配置的

a.公共的配置(可以默认)例如:
	MySQL端口号:3306
	redis端口号:6379
	Tomcat端口号:8080
b.个性化的配置(必须配置)例如:
	1.数据库(使用数据库相关的启动器一定要配置):ip地址,用户名,密码
  1. 在springboot项目中,所有的组件功能开启都需要在项目启动类上加一个@Enable…注解来实现,但是Eureka客户端发现(注册)功能注解(@EnableDiscoveryClient)可以不用添加。

二、Eureka注册中心

1.综述:

​ 服务的注册、发现、监控中心,属于被动营业者。需要服务的提供者和调用者注册为Eureka客户端,提供者主动到Eureka服务端定时推送(注册)自己的服务信息、调用者主动到Eureka服务端定时拉取已经注册的服务信息

​ Eureka注册中心高可用的实现方法:多个Eureka Server之间也会互相注册为服务,当服务提供者注册到Eureka Server集群中的某个节点时,该节点会把服务的信息同步给集群中的每个节点,从而实现高可用集群。因此,无论客户端访问到Eureka Server集群中的任意一个节点,都可以获取到完整的服务列表信息。

三、ribbo负载均衡

1.所有服务都应该可以集群,既然集群了就要实现负载均衡

2.ribbon实现服务之间相互调用的负载均衡。网关、feign都通过ribbon实现负载均衡。而网关的负载均衡由Nginx实现,Nginx的负载均衡由Nginx集群内部模拟一台虚拟服务器来实现

3.ribbon默认的负载均衡策略是轮询

四、hystrix熔断器

1.简介:Hystix是Netflix开源的一个延迟和容错库,用于隔离访问远程服务、第三方库,防止出现级联失败

2.具体的应用场景:

	微服务中,服务间调用关系错综复杂,一个请求,可能需要调用多个微服务接口才能实现,会形成非常复杂的调用链路。
	例如:一次业务请求,需要调用A、B、C、D四个服务,这四个服务又可能调用其它服务。
	如果微服务D发生异常,请求阻塞,用户不会得到响应,则tomcat的这个线程不会释放,于是越来越多的用户请求到来,越来越多的线程会阻塞
	服务器支持的线程和并发数有限,请求一直阻塞,会导致服务器资源耗尽,从而导致所有其它服务都不可用,形成雪崩效应。

Hystix解决雪崩问题的手段主要是服务降级,包括:

  • 线程隔离
  • 服务熔断

五、zuul网关(或APIGateway)

1.综述:

​ Zuul作为网关的其中一个重要功能,就是实现请求的鉴权。而这个动作我们往往是通过Zuul提供的过滤器来实现的。

1.1.接收请求,解析请求
1.2.根据请求,选取请求实例  (ip:port)
1.3.重新封装请求:头、参数
1.4.请求发起

2.1解析响应(排雷,过滤敏感信息)
2.2重新封装(网管认为安全的)
2.3将响应返回给客户端

2.核心:zuul核心是一个servlet

3.应用

​ Zuul中默认就已经集成了Ribbon负载均衡Hystix熔断机制。但是所有的超时策略都是走的默认值,比如熔断超时时间只有1S,很容易就触发了。因此建议我们手动进行配置:

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 6000
ribbon:
  ConnectTimeout: 1000
  ReadTimeout: 2000
  MaxAutoRetries: 0
  MaxAutoRetriesNextServer: 0

六、feign(rest服务封装)

1.简介:Feign可以把Rest的请求进行隐藏,伪装成类似SpringMVC的Controller一样。你不用再自己拼接url,拼接参数等等操作,一切都交给Feign去做。

2.负载均衡:Feign中本身已经集成了Ribbon依赖和自动配置:

3.Hystix支持(了解):Feign默认也有对Hystix的集成。只不过,默认情况下是关闭的。我们需要通过下面的参数来开启:

feign:
  hystrix:
    enabled: true # 开启Feign的熔断功能

七、ConfigServer配置中心

八、构建web项目步骤

1.构建springboot父工程:例如cloud_parent

1.打包方式改成pom
  <packaging>pom</packaging>
2.引入Springboot父启动器
	<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.6.RELEASE</version>
        <relativePath/>
    </parent>
3.锁定基本要用的依赖版本
	<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.SR2</spring-cloud.version>
        <mapper.starter.version>2.0.4</mapper.starter.version>
        <mysql.version>5.1.46</mysql.version>
        <pageHelper.starter.version>1.2.5</pageHelper.starter.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <!-- springCloud -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- 通用Mapper启动器 -->
            <dependency>
                <groupId>tk.mybatis</groupId>
                <artifactId>mapper-spring-boot-starter</artifactId>
                <version>${mapper.starter.version}</version>
            </dependency>
            <!-- mysql驱动 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
3.引入web打包插件
	<build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

2.构建子工程-Eureka注册中心

2.1.单机版Eureka注册中心

1.编辑pom文件,引入依赖

1.继承父工程 cloud_parent
2.引入Eureka服务端依赖
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>

2.编写启动类

@SpringBootApplication
@EnableEurekaServer // 声明这个应用是一个EurekaServer
public class EurekaServer {
	public static void main(String[] args) {
		SpringApplication.run(EurekaServer.class, args);
	}
}

3.编写配置

server:
  port: 10086
spring:
  application:
    name: eureka-server # 应用名称,会在Eureka中作为服务的id标识(serviceId)
#配置Eureka客户端相关
eureka:
  client:
    service-url: # EurekaServer的地址,现在是自己的地址,如果是集群,需要写其它Server的地址。
      defaultZone: http://127.0.0.1:10086/eureka
    register-with-eureka: false # 不注册自己
    fetch-registry: false #不拉取服务

2.2.实现高可用Eureka注册中心

1.如果有三个Eureka,则每一个EurekaServer都需要注册到其它几个Eureka服务中,例如:有三个分别为10086、10087、10089,则:

  • 10086要注册到10087和10088上
  • 10087要注册到10086和10088上
  • 100898要注册到10086和10087上

2.修改原来的EurekaServer配置:

注:三台EurekaServer的开发步骤一样,只是配置的不同

第一台

server:
  port: 10086 # 端口
spring:
  application:
    name: eureka-server # 应用名称,会在Eureka中显示
eureka:
  client:
    service-url: # 配置其他Eureka服务的地址,而不是自己,比如10087
      defaultZone: http://127.0.0.1:10087/eureka,http://127.0.0.1:10088/eureka

第二台

server:
  port: 10087 # 端口
spring:
  application:
    name: eureka-server # 应用名称,会在Eureka中显示
eureka:
  client:
    service-url: # 配置其他Eureka服务的地址,而不是自己,比如10087
      defaultZone: http://127.0.0.1:10086/eureka,http://127.0.0.1:10088/eureka

第三台

server:
  port: 10088 # 端口
spring:
  application:
    name: eureka-server # 应用名称,会在Eureka中显示
eureka:
  client:
    service-url: # 配置其他Eureka服务的地址,而不是自己,比如10087
      defaultZone: http://127.0.0.1:10086/eureka,http://127.0.0.1:10087/eureka

3.构建子工程-服务的提供者:例如user_service

1.编辑pom文件,引入依赖
1.继承父工程 cloud_parent
2.引入web启动器依赖
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
3.引入数据库依赖
	<!-- mysql驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
	<!--mybatis启动器-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.0</version>
        </dependency>
4.引入Eureka客户端依赖
        <!-- Eureka客户端 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

2.编写启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EnableDiscoveryClient // 开启Eureka客户端发现功能
public class UserApplication {

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

3.编写application.yml文件
#1.tomcat端口覆盖
server:
  port: 8081
#2.养成给所有springboot项目命名的习惯
spring:
  application:
    name: user-service

#3.配置数据源
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mybatis://127.0.0.1:3306/mydb01
    username: root
    password: root
#4.配置mybatis
mybatis:
  mapper-locations: mapper/**/*.xml # mapper文件地址
  # 还可以配置 实体类别名映射,驼峰匹配 等

#5.#配置Eureka客户端相关
eureka:
  client:
  	# 5.1EurekaServer地址,多个地址以','隔开
    service-url: 
      defaultZone: http://127.0.0.1:10086/eureka,http://127.0.0.1:10087/eureka,
      http://127.0.0.1:10088/eureka
    # 5.2服务注册
    instance:
      ip-address: 127.0.0.1 # ip地址
      prefer-ip-address: true # 更倾向于使用ip,而不是host名
      # 5.3服务续约:维持心跳(定时向EurekaServer发起Rest请求),告诉EurekaServer:“我还活着”
      lease-expiration-duration-in-seconds: 90
      lease-renewal-interval-in-seconds: 30

4.编写业务代码。。。

4.1对外查询的接口UserController:

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/{id}")
    public User queryById(@PathVariable("id") Long id) {
        return userService.queryById(id);
    }
}

4.2 UserService:

@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    public User queryById(Long id) {
        return userMapper.queryById(id);
    }
}

4.3 UserMapper

public interface UserMapper{
    User queryById(@Param("id") Long id); 
}

4.4 sqly语句

<select id="queryById" resultType="user">
    SELECT FROM t_user WHERE id=#{id}
</select>

4.5 实体类

@Data
public class User {
	private Long id;

    private String userName; // 用户名

    private String password; // 密码
}

4.构建子工程-服务的调用者:例如consumer_demo

1.编辑pom文件,引入依赖
1.继承父工程 cloud_parent
2.引入web启动器依赖
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
3.引入Eureka客户端依赖
    <!-- Eureka客户端 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
4.ribbon:因为Eureka中已经集成了Ribbon,所以我们无需引入新的依赖
5.hystrix
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
6.引入feign依赖
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>

2.编写启动类
@SpringBootApplication
@EnableDiscoveryClient // 开启Eureka客户端
@EnableCircuitBreaker //开启hystrix熔断
@EnableFeignClients // 开启Feign功能
public class ConsumerApplication {

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

3.编写配置
server:
  port: 8080
spring:
  application:
    name: consumer-demo # 应用名称
eureka:
  client:
    service-url: # EurekaServer地址
      defaultZone: http://127.0.0.1:10086/eureka,http://127.0.0.1:10087/eureka,
      http://127.0.0.1:10088/eureka
# 在服务的调用端实施对服务提供方访问的负载均衡控制
ribbon:
  ConnectTimeout: 1000 # 连接超时时长
  ReadTimeout: 2000 # 数据通信超时时长
  MaxAutoRetries: 0 # 当前服务器的重试次数
  MaxAutoRetriesNextServer: 0 # 重试多少次服务
  OkToRetryOnAllOperations: false # 是否对所有的请求方式都重试

4.编写业务代码

4.1 编写ConsumerController使用UserClient访问目标服务(user-service):

@RestController
@RequestMapping("consumer")
@Slf4j
public class ConsumerController {

    @Autowired
    private UserClient userClient;

    @GetMapping("{id}")
    @HystrixCommand(fallbackMethod = "queryByIdFallBack")
    public User queryById(@PathVariable("id") Long id){
        log.info("查询方法执行了")return userClient.queryById(id);
    }
    
    public User queryByIdFallBack(Long id){
        log.error("查询用户信息失败,id:{}", id);
        return new User(id,"","对不起,网络太拥挤了!");
	}
}

4.2 Feign的客户端UserClient

/**
 * 1.这是一个接口,Feign会通过动态代理,帮我们生成实现类。这点跟mybatis的mapper很像
 * 2.`@FeignClient`,声明这是一个Feign客户端,同时通过`value`属性指定服务名称
 * 3.接口中的定义方法,完全采用SpringMVC的注解,Feign会根据注解帮我们生成URL,并访问获取结果
 * 4.feign的客户端已经集成了ribbon负载均衡功能,因此通过feign客户端调用服务提供者时会自动实现负载均 
 *   衡
 */
@FeignClient("user-service")
public interface UserClient {

    @GetMapping("/user/{id}")
    User queryById(@PathVariable("id") Long id);
}

  1. 3实体类
@Data
public class User {
	private Long id;

    private String userName; // 用户名

    private String password; // 密码
}

5.构建子工程-zuul网关:例如zuul-demo

1.编辑pom文件,引入依赖
1.继承父工程 cloud_parent
2.引入zuul启动器依赖
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
	</dependency>

2.编写启动类
@SpringBootApplication
@EnableDiscoveryClient // 开启Eureka客户端
@EnableZuulProxy // 开启Zuul的网关功能
public class ZuulApplication {

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

3.编写配置
server:
  port: 10060 #服务端口
spring: 
  application:  
    name: api-zuul #指定服务名
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka,http://127.0.0.1:10087/eureka,
      http://127.0.0.1:10088/eureka
  instance:
    prefer-ip-address: true
    ip-address: 127.0.0.1
# 添加zuul网关映射规则
zuul:
  routes:
    consumer-demo: # 这里是路由id,随意写
      path: /consumer-demo/** # 这里是映射路径
      serviceId: consumer-demo  # 映射路径对应的实际服务名称

4.编写自定义过滤器类LoginFilter进行鉴权(拦截所有路径)

​ Zuul作为网关的其中一个重要功能,就是实现请求的鉴权。而这个动作我们往往是通过Zuul提供的过滤器来实现的。

/**
 * 1.模拟一个登录的校验。基本逻辑:如果请求中有token参数,则认为请求有效,放行。
 * 2.ZuulFilter是过滤器的顶级父类。在这里我们看一下其中定义的4个最重要的方法
 * 	  filterType:返回字符串,代表过滤器的类型
 *    filterOrder:通过返回的int值来定义过滤器的执行顺序,数字越小优先级越高
 *    shouldFilter:返回一个Boolean值,判断该过滤器是否需要执行。返回true执行,返回false不执行。
 *    run:过滤器的具体业务逻辑
 */
@Component
public class LoginFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return FilterConstants.PRE_DECORATION_FILTER_ORDER - 1;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() throws ZuulException {
        // 获取请求上下文
        RequestContext context = RequestContext.getCurrentContext();
        // 获取request对象
        HttpServletRequest request = context.getRequest();
        // 获取请求参数
        String token = request.getParameter("token");
        // 判断是否存在
        if(StringUtils.isBlank(token)){
            // 不存在,未登录,拦截
            context.setSendZuulResponse(false);
            // 设置返回状态码
            context.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
        }
        return null;
    }
}

5.浏览器请求网关进行测试。分别请求如下地址:

​ 不带token的路径,拦截: localhost:10060/consumer-demo/consumer/3

​ 带token的路径,成功: localhost:10060/consumer-demo/consumer/3?token=aaa

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值