谷粒商城_02_Nacos、网关

谷粒商城_01_环境搭建

SpringCloud Alibaba简介

测试member和coupon的远程调用

想要获取当前会员领取到的所有优惠券。先去注册中心找优惠券服务注册中心调一台优惠券服务器给会员,会员服务器发送请求给这台优惠券服务器,然后对方响应。

Feign与注册中心spring cloud feign,声明式远程调用

Feign是一个声明式的HTTP客户端,他的目的就是让远程调用更加简单。给远程服务发的是HTTP请求。他还整合了Ribbon(负载均衡)和Hystrix(熔断服务)

1、会员服务想要远程调用优惠券服务,只需要给会员服务(member)里引入openfeign依赖,他就有了远程调用其他服务的能力。

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

2、在coupon中修改如下的内容

@RequestMapping("coupon/coupon")
public class CouponController {
    @Autowired
    private CouponService couponService;

    @RequestMapping("/member/list")
    public R membercoupons(){    //全系统的所有返回都返回R
        // 应该去数据库查用户对于的优惠券,但这个我们简化了,不去数据库查了,构造了一个优惠券给他返回
        CouponEntity couponEntity = new CouponEntity();
        couponEntity.setCouponName("满100减10");//优惠券的名字
        return R.ok().put("coupons",Arrays.asList(couponEntity));
    }
}

3、这样我们准备好了优惠券的调用内容,创建feign包并在member的配置类上加注解@EnableFeignClients(basePackages="com.liu.gulimall.member.feign"),告诉spring这里面是一个远程调用客户端,member要调用的所有接口

@SpringBootApplication
@MapperScan("com.liu.gulimall.member.dao")
@EnableDiscoveryClient
@EnableFeignClients(basePackages="com.liu.gulimall.member.feign")
public class GulimallMemberApplication {
    public static void main(String[] args) {
        SpringApplication.run(GulimallMemberApplication.class, args);
    }
}

4、那么要调用什么东西呢?就是我们刚才写的优惠券的功能,复制函数部分,在member的com.liu.gulimall.member.feign包下新建类:

@FeignClient("gulimall-coupon") // 告诉spring cloud这个接口是一个远程客户端,要先调用gulimall-coupon这个服务,再去调用coupon服务中/coupon/coupon/member/list对应的方法
public interface CouponFeignService {
    @RequestMapping("/coupon/coupon/member/list") // 这一块路径得写全
    public R membercoupons();// 得到一个R对象
}

5、然后我们在member的Controller中写一个测试请求

@RestController
@RequestMapping("member/member")
public class MemberController {
    @Autowired
    private MemberService memberService;

    @Autowired
    CouponFeignService couponFeignService;

    /**
     * 测试我们会员服务与优惠券服务的调用
     * @return
     */
    @RequestMapping("/coupons")
    public R test(){
        MemberEntity memberEntity = new MemberEntity();
        memberEntity.setNickname("张三");
        R membercoupons = couponFeignService.membercoupons(); // 假设张三去数据库查了后返回了张三的优惠券信息

        // 打印会员和优惠券信息,这里的coupons是远程返回结果中的
        return R.ok().put("member",memberEntity).put("coupons",membercoupons.get("coupons"));
    }
}

6、重新启动服务,访问:http://localhost:8000/menber/member/coupons

http://localhost:8000/member/member/coupons
{"msg":"success","code":0,"coupons":[{"id":null,"couponType":null,"couponImg":null,"couponName":"满100减10","num":null,"amount":null,"perLimit":null,"minPoint":null,"startTime":null,"endTime":null,"useType":null,"note":null,"publishCount":null,"useCount":null,"receiveCount":null,"enableStartTime":null,"enableEndTime":null,"code":null,"memberLevel":null,"publish":null}],"member":{"id":null,"levelId":null,"username":null,"password":null,"nickname":"张三","mobile":null,"email":null,"header":null,"gender":null,"birth":null,"city":null,"job":null,"sign":null,"sourceType":null,"integration":null,"growth":null,"status":null,"createTime":null}}

7、这里可能会少依赖出错

<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-loadbalancer -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
    <version>3.0.4</version>
</dependency>

Receiver class org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient does not define or inherit an implementation of the resolved method

<!--服务注册/发现-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </exclusion>
    </exclusions>
</dependency>

配置中心

我们还可以用nacos作为配置中心。配置中心的意思是不在application.properties等文件中配置了,而是放到nacos配置中心公用,这样无需服务上线后要修改配置时重启服务。

1、引入配置中心依赖,放到common中

<!--配置中心来做配置管理-->
<dependency>
     <groupId>com.alibaba.cloud</groupId>
     <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
 </dependency>

2、在coupons项目中创建/src/main/resources/bootstrap.properties ,这个文件是springboot里规定的,他优先级别比application.properties高,并且在common里面导入bootstrap依赖

# 改名字,对应nacos里的配置文件名
spring.application.name=gulimall-coupon
# 配置中心的地址,这里配置中心还是nacos
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-bootstrap -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bootstrap</artifactId>
    <version>3.0.4</version>
</dependency>

3、测试在我们的application.properties中设置coupon.user.name = zhangsan、coupon.user.age =18

@RestController

@RequestMapping("coupon/coupon")
public class CouponController {
    @Autowired
    private CouponService couponService;

    @Value("${coupon.user.name}")// 从application.properties中获取 // 不要写user.name,他是环境里的变量
    private String name;
    @Value("${coupon.user.age}")
    private Integer age;
    @RequestMapping("/test")
    public R test(){
        return R.ok().put("name",name).put("age",age);
	}
}

启动访问coupon服务:http://localhost:7000/coupon/coupon/test:{“msg”:“success”,“code”:0,“name”:“zhangsan”,“age”:18}

4、浏览器去nacos里的配置列表,点击+号,data ID:gulimall-coupon.properties,配置,这里是服务名,规定的

在这里插入图片描述

# gulimall-coupon.properties
coupon.user.name="张三"      
coupon.user.age=12

5、但是怎么实时修改呢?实际生产中不能重启应用。在coupon的控制层上加@RefreshScope,表示实时刷新每次配置都从配置中心去获取配置,重启nacos、重启coupon,访问:http://localhost:7000/coupon/coupon/test{"msg":"success","code":0,"name":"\"张三\"","age":12}

6、最终代码如下

@RefreshScope
@RestController
@RequestMapping("coupon/coupon")
public class CouponController {
    @Autowired
    private CouponService couponService;

    @Value("${coupon.user.name}")// 从application.properties中获取 //不要写user.name,他是环境里的变量
    private String name;
    @Value("${coupon.user.age}")
    private Integer age;
    @RequestMapping("/test")
    public R test(){

        return R.ok().put("name",name).put("age",age);
    }

}

7、重启后,在nacos浏览器里修改配置,修改就可以观察到能动态修改了nacos的配置内容优先于项目本地的配置内容。

小结

  • 引入依赖spring-cloud-starter-alibaba-nacos-config,starter表示启动就回去找配置,所以下一步编写配置
  • 编写bootstrap.properties
  • 在nacos配置中心添加一个数据集(Data Id),默认规则:应用名.properties:gulimall-coupon.properties,在这里面进行配置编写
  • 动态获取配置,添加注解:@RefreshScope、@Value("${配置项的名}")获取配置,配置中心优先与服务配置的相同项

配置中心进阶

在nacos浏览器中还可以配置:

  • 命名空间:用作配置隔离。(一般每个微服务一个命名空间),默认public。默认新增的配置都在public空间下

开发、测试、开发可以用命名空间分割(dev、test、prop)。properties每个空间有一份,在bootstrap.properties里配置采用那个命名空间的配置文件。默认是采用public中的

1、我们使用prop中的环境,利用命名空间做环境隔离

在这里插入图片描述

spring.cloud.nacos.config.namespace=7fbf2f71-d0b3-4e96-9317-5e548e344268
# 可以选择对应的命名空间 ,即写上对应环境的命名空间ID
# 启动访问,发现用的prop中的配置

​ 2、为每个微服务配置一个命名空间,微服务互相隔离,不然每个会使每一个空间下(public、dev等)有大量的配置文件

在这里插入图片描述

​ 在微服务gulimall-coupon中就采用自己的命名空间

spring.cloud.nacos.config.namespace=7818bdad-b382-4eab-ac92-974e486af35e
# 可以选择对应的命名空间 ,即写上对应环境的命名空间ID
  • 配置集:所有的配置的集合。一组相关或不相关配置项的集合。

  • 配置集ID:类似于配置文件名,即Data ID

  • 配置分组:默认所有的配置集都属于DEFAULT_GROUP。自己可以创建分组,比如双十一,618,双十二

在这里插入图片描述

​ 配置bootstrap.properties

spring.cloud.nacos.config.group=1111 # 采用双十一分组,默认是DEFAULT_GROUP
  • 最终方案每个微服务创建自己的命名空间,然后使用配置分组区分环境(dev/test/prod)

在这里插入图片描述

spring.cloud.nacos.config.group=dev # prod、、、等
# bootstrap.properties的总配置
spring.application.name=gulimall-coupon
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.namespace=7818bdad-b382-4eab-ac92-974e486af35e
spring.cloud.nacos.config.group=dev

由于配置文件中的内容会越来越多,我们采用多个配置文件来拆分文件内容

  • datasource.yml

在这里插入图片描述

  • other.yml

在这里插入图片描述

# spring.cloud.nacos.config.group=dev
# 相当于加载了一个配置文件,refresh动态刷新
spring.cloud.nacos.config.ext-config[0].data-id=datasource.yml
spring.cloud.nacos.config.ext-config[0].group=dev
spring.cloud.nacos.config.ext-config[0].refresh=true 

spring.cloud.nacos.config.ext-config[1].data-id=mybatis.yml
spring.cloud.nacos.config.ext-config[1].group=dev
spring.cloud.nacos.config.ext-config[1].refresh=true

spring.cloud.nacos.config.ext-config[2].data-id=other.yml
spring.cloud.nacos.config.ext-config[2].group=dev
spring.cloud.nacos.config.ext-config[2].refresh=true

在这里插入图片描述

  • 上图说明会去读取我们的四个配置文件,但是由于在nacos中我们把gulimall-coupon.properties的默认分组删除了,所以用的服务中的配置

在这里插入图片描述

小结

  • 微服务的任何配置信息,配置文件都可以放在配置中心中
  • 只需要在bootsrap.properties中说明加载 配置中心的哪些配置文件即可
  • 以前springboot中的任何方法从配置文件中获取的值,都能使用。@Value、@ConfigurationProperties等等
  • 配置中心有的优先使用配置中心的

网关

spring cloud的gateway组件做网关功能。网关是请求浏览的入口,常用功能包括路由转发,权限校验,限流控制等。springcloud gateway取代了zuul网关。

网关作用?

  • 发送请求需要知道商品服务的地址,如果商品服务器有100服务器,1号掉线后,又得重新修改请求地址,所以需要网关动态地管理,他能从注册中心中实时地感知某个服务上线还是下线。

  • 请求也要加上询问权限,看用户有没有权限访问这个请求,也需要网关。

spring-cloud-gateway官网:https://spring.io/projects/spring-cloud-gateway

spring-cloud-gateway文档:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/

spring-cloud 中文网:https://www.springcloud.cc/

三大核心概念:

Route路由: The basic building block of the gateway. It is defined by an ID, a destination URI, a collection of predicates断言, and a collection of filters. A route is matched if the aggregate predicate is true. 发一个请求给网关,网关要将请求路由到指定的服务。路由有id,目的地uri,断言的集合,匹配了断言就能到达指定位置,

Predicate断言: This is a Java 8 Function Predicate. The input type is a Spring Framework ServerWebExchange. This lets you match on anything from the HTTP request, such as headers or parameters. 就是java里的断言函数,匹配请求里的任何信息,包括请求头等

Filter过滤: These are instances of Spring Framework GatewayFilter that have been constructed with a specific factory. Here, you can modify requests and responses before or after sending the downstream request.
过滤器请求和响应都可以被修改。客户端发请求给服务端。中间有网关。先交给映射器,如果能处理就交给handler处理,然后交给一系列filer,然后给指定的服务,再返回回来给客户端。

在这里插入图片描述

创建模块gulimall-gateway

  • spring模块,导入gateway依赖项目即可
  • 在这里插入图片描述

1、在pom.xml引入gulimall-common

<dependency>
    <groupId>com.liu.gulimall</groupId>
    <artifactId>gulimall-common</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>
<!--版本环境需保持一致-->
<spring-boot.version>2.6.1</spring-boot.version>
<spring-cloud.version>2021.0.0</spring-cloud.version>

2、开启注册服务发现@EnableDiscoveryClient

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) 
// 这里是因为我们引入common的依赖,他里面有mybatis的数据源依赖,但是我们的gateway中没有使用,会导致一些错误,所以我们要排除数据源依赖可以在pom中exclusions排除依赖,或者直接在启动的时候加上exclude
@EnableDiscoveryClient
public class GulimallGatewayApplication {

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

}

3、在applicaion.properties中配置nacos注册中心地址

spring.application.name=gulimall-gateway
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
# 因为我们是通过网关来请求跳转所以不采用8080,自己配置
server.port=88 

4、创建bootstrap.properties填写配置中心地址

gatewayspring.application.name=gulimall-coupon
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
# 命名空间gateway的id
spring.cloud.nacos.config.namespace=d1e3e651-9bc0-4cfe-a65f-7ffde3547272 

5、nacos里创建命名空间gateway,然后在命名空间里创建文件gulimall-gateway.yml

spring:
    application:
        name: gulimall-gateway

6、在项目里创建application.yml,配置网关信息

spring:
  cloud:
    gateway:
      # 路由规则
      routes:
        - id: baidu_route
          uri: http://www.baidu.com
          # 断言,判断成功才去跳转到指定地方 :www.baidu.com
          predicates:
            # 当参数url==baidu就跳转到www.baidu.com
            - Query=url,baidu
        - id: qq_route
          uri: http://www.qq.com
          predicates:
            - Query=url,qq

测试 http://localhost:88?url=baidu 跳到百度页面
测试 http://localhost:88?url=qq 跳到qq页面

  • 34
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 30
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

早上真起不来!

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

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

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

打赏作者

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

抵扣说明:

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

余额充值