Java面试之搭建一个SpringCloud Alibaba项目

1.创建一个maven项目(父工程)

在这里插入图片描述
删除的多余的src文件夹

引入公共依声明(版本管理):

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <packaging>pom</packaging>
  <modules>
    <module>userservice</module>
    <module>gateway</module>
    <module>common</module>
  </modules>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.6.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>

  <groupId>cn.redocloud</groupId>
  <artifactId>crazy</artifactId>
  <version>1.0</version>

  <name>crazy Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <!-- Spring Settings -->
    <spring-boot-admin.version>2.1.5</spring-boot-admin.version>
    <spring-cloud.version>Greenwich.SR2</spring-cloud.version>
    <spring-cloud-alibaba.version>0.9.0.RELEASE</spring-cloud-alibaba.version>
  </properties>

  <dependencies>
    <!-- lombok -->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <optional>true</optional>
    </dependency>
  </dependencies>

  <dependencyManagement>
    <dependencies>
      <!-- spring cloud -->
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>${spring-cloud.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>

      <!-- spring cloud alibaba -->
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-alibaba-dependencies</artifactId>
        <version>${spring-cloud-alibaba.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>

  </build>
</project>

2.创建公共模块(一般是工具类或者公共的配置或者接口、注解、枚举等)

当然我这里只是加了一个工具类,这里暂时没有什么依赖,按需导入对应的一些工具包,如fastjson、gson等
在这里插入图片描述

3.创建Gateway模块

如创建一个gateway网关:
选中父模块=>New=>Module
在这里插入图片描述

配置模块信息(我这里报错是因为我已经创建了gateway这个工程了,这里只是作为演示)

在这里插入图片描述

导入依赖:

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>crazy</artifactId>
        <groupId>cn.redocloud</groupId>
        <version>1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>gateway</artifactId>

    <name>gateway</name>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <!--这就是上面我们定义的公共模块的包,导入后才能使用,否者是识别不到的-->
        <dependency>
            <groupId>cn.redocloud</groupId>
            <artifactId>common</artifactId>
            <version>1.0</version>
        </dependency>
    </dependencies>
</project>

如下:
在这里插入图片描述
gateway的配置:

server:
  port: 9000
spring:
  profiles:
    active: dev
  application:
    name: gateway
  cloud:
    gateway:
      routes:
        - id: userservice
          uri: lb://userservice
          predicates:
            - Path=/user/**

以上url为满足predicates中定义的条件后访问的服务
lb://服务名 lb的含义是均衡负载 调用服务
Path = /user/**是指请求的url满足条件为/user开头时会访问uri中定义的服务或者url或者websocket地址

3.创建userservice

目的:查看gateway是否真的做到了均衡负载
依赖如下:

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <parent>
    <artifactId>crazy</artifactId>
    <groupId>cn.redocloud</groupId>
    <version>1.0</version>
  </parent>
  <modelVersion>4.0.0</modelVersion>

  <groupId>cn.redocloud</groupId>
  <artifactId>userservice</artifactId>
  <version>1.0</version>

  <name>userservice Maven Webapp</name>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
  </dependencies>
</project>

bootstrap.yml

spring:
  cloud:
    nacos:
      config:
        namespace: 9eeffe66-d561-4b00-a42c-38d13fd5cd09
        group: dev
        server-addr: 127.0.0.1:8848
        file-extension: yaml
      discovery:
        namespace: 9eeffe66-d561-4b00-a42c-38d13fd5cd09
        server-addr: 127.0.0.1:8848

创建启动类+控制器
在这里插入图片描述
因为要测试是否做到负载均衡,所以这里需要启动两个userservice
第一个userservice的配置如下:端口为9001

server:
  port: 9001
spring:
  profiles:
    active: dev
  application:
    name: userservice

选中Edit Configurations
在这里插入图片描述

点击勾选允许并行运行Allow parallel run
在这里插入图片描述

启动:(不要用Jrebel启动)
在这里插入图片描述
启动成功,端口为9001

配置第二个userservice:
将刚刚的配置文件改为,仅修改端口为9002

server:
  port: 9002
spring:
  profiles:
    active: dev
  application:
    name: userservice

修改Controller内容返回User2:
在这里插入图片描述
同样,Edit Configurations
新增一个启动器 UserServiceApplication2,启动类仍然为UserServiceApplication类
点击勾选允许并行运行Allow parallel run
启动(不要使用Jrebel启动)
在这里插入图片描述

访问同一个接口:
在这里插入图片描述

在这里插入图片描述
出现两种不同的返回,说明负载均衡成功了,当然这是网关的均衡负载。

4.创建OrderService

目的:整合openFeign ,测试OpenFeign的均衡负载
POM如下

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>crazy</artifactId>
        <groupId>cn.redocloud</groupId>
        <version>1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>orderservice</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
    </dependencies>

</project>

application.yml配置

server:
  port: 9003
spring:
  profiles:
    active: dev
  application:
    name: orderservice
feign:
  hystrix:
    enabled: true #默认关闭 不开的话,如果FeignClient的fallback不生效

bootstrap.yml 同上没有变化

spring:
  cloud:
    nacos:
      config:
        namespace: 9eeffe66-d561-4b00-a42c-38d13fd5cd09
        group: dev
        server-addr: 127.0.0.1:8848
        file-extension: yaml
      discovery:
        namespace: 9eeffe66-d561-4b00-a42c-38d13fd5cd09
        server-addr: 127.0.0.1:8848

编写FeignClient,调用上面的userservice服务

@FeignClient(name = "userservice",fallback = UserClientFallback.class)
public interface UserClient {

    @RequestMapping("/user")
    String getUser();
}

设置熔断类:

@Component
public class UserClientFallback implements UserClient {
    @Override
    public String getUser() {
        return "null";
    }
}

在Controller中注入:

@RequestMapping("/order")
@RestController
@Slf4j
public class OrderController {

    @Autowired
    UserClient userClient;

    @RequestMapping
    public String getUser(){
        log.info("类为{}",userClient);
        return userClient.getUser();
    }

}

启动orderservice,访问order接口:
在这里插入图片描述
在这里插入图片描述

可以看到访问同一个接口时,两个结果的不同,这就是openfeign自带的均衡负载(当然,这个从业务上将不应该如此,而是应该user服务调用orderservice,这里只是做简单示例,具体需要考虑业务)

测试熔断:关闭两个userservice服务,再访问/order接口:
在这里插入图片描述
返回的是我们在熔断类中定义的信息(这里必须配置
feign:
hystrix:
enabled: true #默认关闭 否则返回的为500错误)

5.Gateway中Redis限流

引入依赖

        <!--#### Redis限流  start ####-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
        </dependency>

        <!-- commons-pool2对象池依赖 这个是需要引入的,spring-boot-starter-data-redis-reactive部分地方依赖了这块内容-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>
        <!--#### Redis限流  end ####-->

在yml中新增filters,名称必须为RequestRateLimiter,以下配置参数限流和ip限流
在这里插入图片描述

配置限流方式:(以下仅为其中一种限流,也可以在过滤器中重写方法的形式来自己使用Redis等实现此功能)

/**
 * @Author: ChenTaoTao
 * @Date: 2021/12/20 22:24
 * @Describe:
 */
@Configuration
public class LimiterConfig {
    @Bean
    KeyResolver userKeyResolver() {
        return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
    }

    //定义一个ipKeyResolver
    @Bean
    public KeyResolver ipKeyResolver(){
        //新写法 lamda表达式 相当于new KeyResolver(){ 重写方法 }
        return exchange -> {
            //获取访问者的ip地址, 通过访问者ip地址进行限流, 限流使用的是Redis中的令牌桶算法
            String hostString = exchange.getRequest().getRemoteAddress().getHostString();
            return Mono.just(hostString);
        };
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SinceThenLater

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值