【无标题】day04 SpringCloud实用篇02

今日重点
一、nacos配置中心

在弹出的表单中,填写配置信息:

项目的核心配置,需要热更新的配置才有放到nacos管理的必要。基本不会变更的一些配置还是保存在微服务本地比较好。


二、配置中心的使用步骤

1)引入nacos-config依赖

首先,在user-service服务中,引入nacos-config的客户端依赖:

<!--nacos配置管理依赖-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

2)添加bootstrap.yaml

然后,在user-service中添加一个bootstrap.yaml文件,内容如下:

spring:
  application:
    name: userservice # 服务名称
  cloud: #nacos注册中心配置内容
    nacos:
      discovery:
        server-addr: 192.168.94.129:8848
        cluster-name: HZ
        #开发环境的区别
        namespace: 73be46a4-c53c-4b10-a68f-205698afef0e
        #区分统一环境下的不同项目组
        group: cloud_project
      config:
        server-addr: 192.168.94.129:8848
        cluster-name: HZ
        namespace: 73be46a4-c53c-4b10-a68f-205698afef0e
        group: cloud_project
        file-extension: yml
​
​
#修改日志级别,可以显示出读取的配置信息
logging:
  level:
    cn.itcast: debug
    com:
      alibaba:
        cloud:
          nacos:
            client: debug

3)读取nacos配置

在user-service中的UserController中添加业务逻辑,读取pattern.dateformat配置:


三、热更新

要实现配置热更新,可以使用两种方式:

1.2.1.方式一

在@Value注入的变量所在类上添加注解@RefreshScope:

1.2.2.方式二

使用@ConfigurationProperties注解代替@Value注解。

在user-service服务中,添加一个类,读取patterrn.dateformat属性:

package cn.itcast.user.config;
​
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
​
@Component
@Data
@ConfigurationProperties(prefix = "pattern")
public class PatternProperties {
    private String dateformat;
}

在UserController中使用这个类代替@Value:

完整代码:

package cn.itcast.user.web;
​
import cn.itcast.user.config.PatternProperties;
import cn.itcast.user.pojo.User;
import cn.itcast.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;
​
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
​
@Slf4j
@RestController
@RequestMapping("/user")
// @RefreshScope
public class UserController {
​
    @Autowired
    private UserService userService;
​
    //@Value("${pattern.dateformat}")
    //private String dateformat;
​
    @Autowired
    private PatternProperties properties;
​
    /**
     * 获取当前系统时间,并进行格式化
     * @return
     */
    // @GetMapping("now")
    // public String now(){
    //     System.out.println("日志参数的格式为: "+dateformat);
    //     return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dateformat));
    // }
    @GetMapping("now")
    public String now(){
        System.out.println("日志参数的格式为: "+properties.toString());
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(properties.getDateformat()));
    }
​
    @GetMapping("prop")
    public PatternProperties prop(){
       return properties;
    }
​
    /**
     * 路径: /user/110
     *
     * @param id 用户id
     * @return 用户
     */
    @GetMapping("/{id}")
    public User queryById(@PathVariable("id") Long id) {
        return userService.queryById(id);
    }
}
​


四、多环境支持

项目开发过程中,可能会存在多种环境,并且每一种环境所设置的配置都是不同的。nacos可以同时支持多环境配置,可以满足生产环境下的需求。

​ 不同的开发环境:namespace 区分

​ 不同的开发组:group 区分

​ 不同的项目: dataid 区分

​ 不同种类的配置:profile


五、共享配置

1)在nacos中添加 datasource-config.yml

如下图:

配置信息:

spring:
  datasource:
    url: jdbc:mysql://192.168.94.129:3306/xxxxx?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false
    username: root
    password: itcast142
    driver-class-name: com.mysql.jdbc.Driver

2)在user-service和order-service的bootstrap.yml文件中添加内容

spring:
  cloud:
    nacos:
      config:
        shared-configs:
          - dataId: db-config.yml


六、配置持久化

1)mysql中新建nacos_config数据库,并执行资料/nacos持久化下的nacos-mysql.sql

参考github:nacos/nacos-mysql.sql at master · alibaba/nacos · GitHub

如果github上不去,可以直接在今天的资料里nacos_config.sql文件直接导入到自己的数据库中。

2)进入nacos容器

docker exec -it nacos /bin/bash

3)修改conf目录下application.properties

spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://自己的ip:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=自己的密码

记得将文件中的原有配置注释掉,要不然会和上面新增配置内容冲突,可以查考今天下发资料中的application.properties 文件。

4)重启nacos容器

docker restart nacos
​
#查看nacos的日志
docker logs -f nacos 

访问nacos可以发现,配置中心中没有了配置内容,因为nacos已经连接了mysql,mysql中并没有配置文件


七、远程调用Feign

先来看我们以前利用RestTemplate发起远程调用的代码:

存在下面的问题:

•代码可读性差,编程体验不统一

•参数复杂URL难以维护

Feign是一个声明式的http客户端,官方地址:https://github.com/OpenFeign/feign

其作用就是帮助我们优雅的实现http请求的发送,解决上面提到的问题。

Feign: 代替消费者向提供者发送请求,并接受返回结果
    openfeign: SpringCloud官方提供的组件


八、使用步骤

使用Feign的步骤:

① 引入依赖

② 添加@EnableFeignClients注解

③ 编写FeignClient接口

④ 使用FeignClient中定义的方法代替RestTemplate


九、日志级别配置

也可以基于Java代码来修改日志级别,先声明一个类,然后声明一个Logger.Level的对象:

public class DefaultFeignConfiguration  {
    @Bean
    public Logger.Level feignLogLevel(){
        return Logger.Level.BASIC; // 日志级别为BASIC
    }
}

如果要全局生效,将其放到启动类的@EnableFeignClients这个注解中:

package cn.itcast.order;
​
import cn.itcast.order.config.DefaultFeignConfiguration;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
​
@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
// 配置类的方式开启全局日志记录
@EnableFeignClients(defaultConfiguration = DefaultFeignConfiguration.class) // 开启feign客户端的支持
@EnableFeignClients // 开启feign客户端的支持
public class OrderApplication {
​
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }
​
   //......
}

如果是局部生效,则把它放到对应的@FeignClient这个注解中:

package cn.itcast.order.feign;
​
import cn.itcast.order.config.DefaultFeignConfiguration;
import cn.itcast.order.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
// 指定服务日志配置
@FeignClient(value = "userservice",configuration = DefaultFeignConfiguration.class)
public interface UserFeignClient {
    @GetMapping("/user/{id}")
    User queryById(@PathVariable("id") Long id);
}
​


十、优化调用性能

总结,Feign的优化:

  1. 日志级别尽量用basic

2.使用HttpClient或OKHttp代替URLConnection

① 引入feign-httpClient依赖

② 配置文件开启httpClient功能,设置连接池参数


十一、最佳实践

所谓最近实践,就是使用过程中总结的经验,最好的一种使用方式。

自习观察可以发现,Feign的客户端与服务提供者的controller代码非常相似:


十二、网关

1)创建gateway服务,引入依赖

创建服务:

引入依赖:

<!--网关-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--nacos服务发现依赖-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

2)编写启动类

package cn.itcast.gateway;
​
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
​
@SpringBootApplication
public class GatewayApplication {
​
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}

3)编写基础配置和路由规则

创建application.yml文件,内容如下:

server:
  port: 10010 # 网关端口
spring:
  application:
    name: gateway # 服务名称
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 网关路由配置
        - id: user-service # 路由id,自定义,只要唯一即可
          # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址
          uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
            - Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求

我们将符合Path 规则的一切请求,都代理到 uri参数指定的地址。

本例中,我们将 /user/**开头的请求,代理到lb://userservice,lb是负载均衡,根据服务名拉取服务列表,实现负载均衡。

4)重启测试

5重启网关,访问http://localhost:10010/user/1时,符合/user/**规则,请求转发到uri:http://userservice/user/1,得到了结果:


十三、核心功能


十四、断言工厂使用

Spring Cloud Gateway

我们在配置文件中写的断言规则只是字符串,这些字符串会被Predicate Factory读取并处理,转变为路由判断的条件

例如Path=/user/**是按照路径匹配,这个规则是由

org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory类来

处理的,像这样的断言工厂在SpringCloudGateway还有十几个:

名称说明示例
After是某个时间点后的请求- After=2037-01-20T17:42:47.789-07:00[America/Denver]
Before是某个时间点之前的请求- Before=2031-04-13T15:14:47.433+08:00[Asia/Shanghai]
Between是某两个时间点之前的请求- Between=2037-01-20T17:42:47.789-07:00[America/Denver], 2037-01-21T17:42:47.789-07:00[America/Denver]
Cookie请求必须包含某些cookie- Cookie=chocolate, ch.p
Header请求必须包含某些header- Header=X-Request-Id, \d+
Host请求必须是访问某个host(域名)- Host=.somehost.org,.anotherhost.org
Method请求方式必须是指定方式- Method=GET,POST
Path请求路径必须符合指定规则- Path=/red/{segment},/blue/**
Query请求参数必须包含指定参数- Query=name, Jack或者- Query=name
RemoteAddr请求者的ip必须是指定范围- RemoteAddr=192.168.1.1/24
Weight权重处理

我们只需要掌握Path这种路由工程就可以了。


十五、过滤器的使用

全局过滤器的作用也是处理一切进入网关的请求和微服务响应,与GatewayFilter的作用一样。区别在于GatewayFilter通过配置定义,处理逻辑是固定的;而GlobalFilter的逻辑需要自己写代码实现。

定义方式是实现GlobalFilter接口。


十六、跨域问题和解决方案

协议,域名,端口三者中任意一者不同即为跨域

跨域:域名不一致就是跨域,主要包括:

跨域问题:浏览器禁止请求的发起者与服务端发生跨域ajax请求,请求被浏览器拦截的问题

解决方案:CORS,这个以前应该学习过,这里不再赘述了。不知道的 可查看跨域资源共享 CORS 详解 - 阮一峰的网络日志

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值