微服务 尚硅谷SpringCloud

源码地址
cloud-zero参考地址
Spring官网

分布式 > 微服务 > SpringCloud

客户端处理: 负载均衡{Ribbon Feign),断路器中的服务降级 都是是客户端处理
服务端处理:断路器中的服务熔断

一。父工程构建

新建父工程microservicecloud,主要是定义POM文件,将后续子模块公用的jar包统一提出来,类似一个抽象父类
***注意packaging是POM模式***

二。公共子模块API构建(定义一个实体类供各个模块引用)

1.新建模块 cloud-zero-api
2.pom
  <parent>自动生成
  <artifactId>当前Module名称
3.实体类创建
4.其他模块引用
    <dependency>
	    <groupId>com.wind</groupId>
	    <artifactId>cloud-zero-api</artifactId>
	    <version>${project.version}</version>
   </dependency>

三。服务提供者构建

1.新建模块 provider
2.pom
    <parent> 自动生成
    <artifactId> 当前module名称
    <depency>公用API模块
3.application.yml
   a.端口 :8001
   b.Spring 本微服务名称 和数据库连接信息
   c.mybatis 映射文件和实体类所在包
  
server:
port: 8001

spring:
  application:
    name: cloud-zero-user-8001服务提供者
  datasource:
    driverClassName: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/cloud-zero?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
    username: root
    password: root

mybatis:
  type-aliases-package: com.wind.cloud.demo.user.domain    # 所有Entity别名类所在包
  mapper-locations:
    - classpath:mapper/*.xml                            # mapper映射文件
   
4. dao service control增删改查
5. 启动类
   
 测试 localhost:8001/user/list 显示数据

四。将服务注册

a.服务注册中心(7001)建立

Netflix在设计eureka遵循AP原则
自我保护机制:好死不如赖活着(保留错误信息也不删除)

//1.新建模块    
//2.pom    添加相关技术依赖
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
  </dependency>
  
 //3.yml  端口与配置
   server:
      port: 7001
   eureka:
     instance:
          hostname: eureka7001.com #eureka服务端的实例名称
     client:
          register-with-eureka: false     #false表示不向注册中心注册自己。
          fetch-registry: false     #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
          service-url:
             #设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址(单机)。
             defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/     #其他微服务注册进来的地址
             #defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/

//4.启动类
  @SpringBootApplication
  @EnableEurekaServer    表示7001是服务端启动类 ,接收其他微服务注册进来

测试是否成功:localhost:7001有出现eureka界面就是表示Ok
    

b。将已有的服务(8001)注册进Eureka(7001)

//1.pom   引入eureka-client  8001的pom 
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

//2.yml  8001的yml
eureka:
  client: # 客户端注册进eureka服务列表内
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka,        星云:defaultZone: http://192.168.1.15:8572/eureka/
        http://eureka7002.com:7002/eureka,
        http://eureka7003.com:7003/eureka  #//是7001里面的defaultZone的地址
  instance:
    instance-id:  ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
    prefer-ip-address: true
    
info:
  app.name: cloud-zero
  company.name: www.zmrit.com
  build.artifactId: hahaha
  build.version: 2020032001  
  
/3.主启动类 添加注解
@EnableEurekaClient     表示8001服务启动后会自动注册进eureka服务中

测试是否成功:先启动7001再启动8001,输入 localhost:7001 出现的界面中Application有内容就表示注册成功

c.Eureka界面信息修改 完善

在服务提供者模块

1.修改显示的微服务名称Application
8001.yml  
spring:
  application:
    name: cloud-zero-user

2.修改超链接显示的内容,和左下角显示的Ip
  8001.yml
  eureka下添加 instance:
           instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port} //超链接显示的内容
            prefer-ip-address: true     # 访问路径可以显示IP地址                                     //左下角显示的内容
    
3.修改点击超链接跳出来显示的内容
  a. 8001.pom添加监控依赖信息
	<dependency>
    		<groupId>org.springframework.boot</groupId>
   		 <artifactId>spring-boot-starter-actuator</artifactId>
	</dependency>
  b. 父工程 pom文件添加构建信息build 可以为空标签
  c. 8001.yml添加 info,与server spring mybatis同等级
    info:
	  app.name: cloud-zero
	  company.name: www.zmrit.com
	  build.artifactId: aaa
	  build1.version:  bbb
	  build12.version2: ccc
	  test.test: aaa

4.修改服务注册地址
  7001 yml的 DefaultZone 和 8001yml的defaultZone

d.Eureka集群配置

1.新建molule,复制7001模块
2.修改host映射配置   作用:使用别名区分不同服务中心
  127.0.0.1 eureka7001.com
  127.0.0.1 eureka7002.com
  127.0.0.1 eureka7003.com
3.修改yml    a.端口/b.hostname/c.defaultZone   	    
server:
   port: 7001
eureka:
  instance:
    hostname: eureka7001.com #eureka服务端的实例名称
    client:
      register-with-eureka: false     #false表示不向注册中心注册自己。
      fetch-registry: false     #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
      service-url:
          #设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址(单机)。
           #defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/               单机写7001
          defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/  集群的话写70027003
       
4.修改8001的yml  defaultZone:注册地址由单机改完集群
eureka:
  client: # 客户端注册进eureka服务列表内
    service-url:
      #defaultZone: http://localhost:7001/eureka
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ 
     
    

f.Eureka服务发现

什么是服务发现:对于注册进eureka里面的微服务,我们可以通过服务发现来获取该服务的发现

1.服务提供者的控制器加上如下内容  8001

   @Autowired
   private DiscoveryClient client;
   
  @RequestMapping(value = "discovery", method = RequestMethod.GET)
  @ResponseBody
  public Object discovery()
 {
       List<String> list = client.getServices();
       System.out.println("**********" + list);
       List<ServiceInstance> srvList = client.getInstances("cloud-zero-USER");
       for (ServiceInstance element : srvList)
       {
           System.out.println(element.getServiceId() + "\t" + element.getHost() + "\t" + element.getPort() + "\t"
                + element.getUri());
        }
       return this.client;
 }

2.还是这个控制器加上 @EnableDiscoveryClient //服务发现

注册到Nacos

1.启动nacos服务,测试访问:http://localhost:8848/nacos     账号:nacos      密码:nacos

2.微服务注册到nacos
	1.pom引入依赖,版本要和项目的springboot一致
	      <!--服务发现-->
		 <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>2.2.4.RELEASE</version>
        </dependency>
      
   2.yml文件指定注册中心(要给这个服务起名字spring.application.name)
   			spring:
			  application:
			    	name: mock
			  cloud:
			    	nacos:
			      		discovery:
			        		server-addr: localhost:8848
			      			namespace:  环境隔离dev uuid 

   3.主启动类加注解@EnableDiscoveryClient, 也可不用加
   4.测试访问nocos服务列表看是否有这个服务

五。消费者 restTemplate

消费者理解为:新加另一种访问路径来访问provider,
端口一般设为80就可以省略端口

1.新建模块 cloud-zero-consumer-user
2.pom                                 见最底下5.2
   <dependencies>             
3.yml
   端口   将服务注册进eureka         见最底下5.3
4.新建 ConfigBean 获取restTemplate  见最底下5.4
5,新建控制器 ConsumerUserController 根据Http工具restTempate发送请求   见最底下5.5
    restTepmplate(url,参数,返回类型)  url为服务提供者的url
6.启动类   @EnableEurekaClient
测试:启动提供者8001  再启动消费者80,通过80的网址也能查到数据表示Ok

六。Ribon 负载均衡

1.初步配置 (prefix由微服务名称代替ip+端口)

Ribbon和Eureka整合后Consumer可以直接调用服务而不用再关心地址和端口号
根据服务名称查询Eureka注册中心的可用列表并轮询

//在80模块 消费者
1.pom添加 ribbon依赖
  <!-- Ribbon相关 -->
   <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
  </dependency>
  
2.configBean的方法添加注解lb   @LoadBalanced

3.consumer访问控制器 
   private static final String REST_URL_PREFIX = "http://localhost:8001"; 改为
   private static final String REST_URL_PREFIX = "http://CLOUD-ZERO-USER";
测试:启动三个注册中心 服务提供者 消费者,看80是否还能正常访问

在这里插入图片描述
2.多个微服务提供者负载均衡测试 (多个服务提供者,连接多个库)

1.新建模块provider-user-8002 和provider-user-8003
 pom拷贝8001
 yml 改端口和数据库地址  (注意:服务名称不能改 spring.application.name)
2.测试
  a.启动三个注册中心   启动三个微服务提供者(并自测通过)   启动消费者
  
  访问消费者 http://localhost/consumer/user/list  每次去查的库不一样

3.指定Ribbon提供的算法
在configBean添加如下代码 (如果不加默认采用RoundRobinRule轮询)

//在configBean添加
@Bean
public IRule myRule(){
    return new RandomRule();   //指定算法代替默认的轮询算法
}

在这里插入图片描述
4…自定义算法

//在80模块
1.添加文件 MySelfRule.class            文件见最底下 6.4的第二种的第一个类
    注意:a.该文件不能在80主启动类的包以子包下(该类所在的包 和启动类所在的包同等级)
         b.该文件类名加@Configuration   方法加@bean
2. 自定义算法MyRandomRule.class(参考源码地址)               文件见最底下 6.4的第二种的第二个类
3.80的主启动类添加注解
  @RibbonClient(name = "USER-PROVIDER", configuration = MySelfRule.class)   //name服务提供者名称  configuration:自定义算法文件

randomRule源码地址

1.添加文件 public class MyRandomRule extends AbstractLoadBalancerRule

2.mySelf文件 改为 return new MyRandomRule();//我自定义为每个机器被访问5次

七 Feign 负载均衡

小程序调用运营平台的功能 ,
   如下写在调用方小程序(接口加注解的方式)
   
1.调用方声明提供方的微服务名称和接口路径
@FeignClient(name = "newenergy-operation-manage-0-0-1",configuration = FeignClientConfiguration.class)
public interface HomePageFeignClient {
    @PostMapping("/api/basic/search/byPricePlanId")
    PricePlanAndDetailsDto getPricePlan(@RequestBody PricePlanDto planId);

    @PostMapping("/api/basic/search/priceRule")
    List<PriceRuleAndDetailsDto>  searchPriceRule(@RequestBody List<String> ids);

    @PostMapping("/api/park/manage/add/reduction/recordByParkAPI")
    Integer addParkReductionRecordByParkAPI(@RequestBody ParkReduceAPIRequestDto requestDto);
}

2.调用方调用使用
homePageFeignClient.addParkReductionRecordByParkAPI(requestDto);

Feign是Netflix开发的声明式、模板化的HTTP客户端, Feign可以帮助我们更快捷、优雅地调用HTTP API。
Feign可以与Eureka和Ribbon组合使用支出负载均衡
Feign通过接口的方法调用服务,之前是Ribbon + restTemplate
Feign集成了Ribbon,并且通过轮询实现了负载均衡功能,而与Ribbon不同的是,Feigh只需要定义接口和添加注解,就可以实现服务的调用

简写:Feign是一个声明式的服务客户端,使得编写Web服务客户端变得非常容易(用接口代替微服务调用rest)

1.API.pom添加Feign依赖  
   	 <!-- Fegin相关 -->
	<dependency>
	      <groupId>org.springframework.cloud</groupId>
	      <artifactId>spring-cloud-starter-openfeign</artifactId>
	</dependency>
	
2.API新建接口文件 RemoteUserService(注意有注解 @FeignClient(value = "CLOUD-ZERO-USER")3.消费者修改Controller的调用方式 (从微服务名称改为接口)

4.消费者启动器去掉@RibbonClient注解,去掉ribbon的作用,注解新增@EnableFeignClients

OpenFeign

只要在调用方处理就好,dubbo服务提供方还要做接口暴露处理(@service)

比如用户服务调用订单服务,如下操作都在用户服务调用方
1.pom引入依赖spring-Cloud-start-openfeign
		<!--openfeign-->
	   <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>2.2.4.RELEASE</version>
        </dependency>
        
2.主启动类添加@EnableFeignClients注解

3.添加OrderFeignService接口,接口上加@FeignClient注解(value为订单微服务名称在nacos看,path为订单服务的总路径),接口下加方法(可直接复制订单的控制层)
	@FeignClient(value = "substationserver", path = "/api/core")
	public interface AzxtFeignService {
	    @GetMapping("/getRouteByCubicle")   //服务提供方的接口路径为 /api/core/getRouteByCubicle
	    List<Object> getRouteByCubicle(@RequestParam String cubicleId);
	}
	
4.在用户模块的控制层,依赖注入@Aotuwired OrderFeignService orderFeignService,然后orderFeignService.methodName()

老林
在这里插入图片描述
在这里插入图片描述
星云调用微信接口

String userInfo = wxFeignClient.getUserInfo(accessTokenDTO.getAccess_token(), accessTokenDTO.getOpenid());
package com.nebula.microservice.authorization.user.feign;

import com.nebula.microservice.authorization.user.constant.UserConstants;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;


@FeignClient(name = "wx", url = UserConstants.WX_AUTH_URL)
public interface WXFeignClient {
    /**
     * 微信小程序授权
     *
     * @param appId     小程序 appId
     * @param secret    小程序 appSecret
     * @param jsCode    登录时获取的 code
     * @param grantType 授权类型,此处只需填写 authorization_code
     * @return 响应消息json
     */
    @GetMapping("/sns/jscode2session")
    String jsCode2Session(@RequestParam(name = "appid") String appId,
                          @RequestParam(name = "secret") String secret,
                          @RequestParam(name = "js_code") String jsCode,
                          @RequestParam(name = "grant_type") String grantType);



    /**
     * 根据前端传来的code获取access_token
     *
     * @param appId     应用唯一标识,在微信开放平台提交应用审核通过后获得
     * @param secret    应用密钥   ,在微信开放平台提交应用审核通过后获得
     * @param code      填写第一步获取的 code 参数
     * @param grantType 授权类型,此处只需填写 authorization_code
     * @return
     */
    @GetMapping("/sns/oauth2/access_token")
    String getAccessToken(
            @RequestParam(name = "appid") String appId,
            @RequestParam(name = "secret") String secret,
            @RequestParam(name = "code") String code,
            @RequestParam(name = "grant_type") String grantType
    );


    /**
     * 根据access_token和openid获取微信用户个人信息
     *
     * @param access_token   调用凭证
     * @param openid         普通用户的标识,对当前开发者帐号唯一
     * @return
     */
    @GetMapping("/sns/userinfo")
    String getUserInfo(
            @RequestParam(name = "access_token") String access_token,
            @RequestParam(name = "openid") String openid
    );


    /**
     * 刷新access_token
     *
     * @param appid
     * @param grant_type
     * @param refresh_token
     * @return
     */
    @GetMapping("/sns/oauth2/refresh_token")
    String refreshToken(
            @RequestParam(name = "appid") String appid,
            @RequestParam(name = "grant_type") String grant_type,
            @RequestParam(name = "refresh_token") String refresh_token
    );


    /**
     * 验证access_token是否有效
     *
     * @param access_token
     * @param openid
     * @return
     */
    @GetMapping("/sns/auth")
    String tokenIsValid(
            @RequestParam(name = "access_token") String access_token,
            @RequestParam(name = "openid") String openid
    );
}

八 Hystrix 断路器

Hystrix是一个处理分布式系统延迟和容错的开源库
作用:保证在某个依赖挂断的情况下,不会导致整个服务系统也跟着挂掉,避免级联故障
服务熔断 服务降级 服务限流 接近实时的监控
源码地址

1.服务熔断

异常调用额外的方法

  如下都在provider模块修改
1. pom(provider)添加Hystrix依赖
     <!--hystrix-->
     <dependency>
	  <groupId>org.springframework.cloud</groupId>
	  <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
     </dependency>
2. 修改Eureka界面超链接显示的内容 (见上方)  这部分主要是为了突出显示它是Hystrix 不操作也行
      instance:
        instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}

3. UserController 查询方法添加注解 @HystrixCommand(fallbackMethod = "processHystrix_Get") 并添加方法 processHystrix_Get
 
    @GetMapping("/{id}")
    @ResponseBody
    @HystrixCommand(fallbackMethod = "processHystrix_Get")
    public User selectUserByGuid(@PathVariable Integer id){
        User user = userMapper.selectUserById(id);
        if (null == user){
           throw new RuntimeException("异常信息啊啊啊");
        }
        return user;
    } 	
 	
    //如果查询不到user,会调用这个方法
    public User processHystrix_Get(@PathVariable Integer id){
       return new User().setId(id).setName("该ID:" + id + " 没有对应的信息,null").setAge(0);
    }

4. 主启动类添加新注解 @EnableCircuitBreaker
				
测试: 启动三个Eureka  启动服务提供者  启动带熔断服务的Consumer  getById查一个不存在的id
2.服务降级

概念: 整体资源快不够了,忍痛将某些服务关掉,待度过难关再开启回来

/**上面服务熔断有两个缺点:
  1.每个方法都要加一个注解和一个回调方法,方法膨胀(即太多方法)
  2.业务主逻辑和异常逻辑混合在一起,耦合性太高()*/API模块
 1.新建一个类 该类实现FallbackFactory<RemoteUserService>   //RemoteUserServices是在Feign时就建立的,当时是为了利用接口调用服务代替Ribbon + restTemplate
   注意:记得在该新建的类上面添加注解:@Component

 2.修改RemoteUserService注解 @FeignClient(value = "CLOUD-ZERO-USER", fallbackFactory = RemoteUserFacllbackFactory.class)

3.Cunsumer模块的yml文件添加
   feign:
      hystrix:
        enabled: true

测试: 启动三个Eureka  启动Provider  
3.监控台 HystrixDashboard 豪猪
//1.新建模块HystrixDashboard
//2.pom 见最底下8.3
<!--hystrix-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<!--hystrix-dashboard-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>

3.启动器
 @SpringBootApplication
 @EnableHystrixDashboard
 public class HystrixDashboardApp{
    public static void main(String[] args){
        SpringApplication.run(HystrixDashboardApp.class);
    }
 }
 
4.yml
 spring:
  application:
    name: cloud-zero-hystrix-dashboard

eureka:
  client: # 客户端注册进eureka服务列表内
    service-url:
      defaultZone: http://localhost:7001/eureka
      #defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
  instance:
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
    prefer-ip-address: true     # 访问路径可以显示IP地址

management:
  endpoints:
    web:
      exposure:
        include: '*'
info:
  app.name: cloud-zero
  company.name: www.zmrit.com
  build.artifactId: @project.artifactId@
  build.version: @project.version@
server:
  port: 9050 

5.服务提供者的yml添加如下,否则报404
management:
  endpoints:
    web:
      exposure:
        include: '*'
        
6.服务提供者8001 8002等的pom都要有监控依赖
  <!--监控依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

测试一: 单独启动hystrixdashboard模块,http://localhost:9001/hystrix ,出现哥豪猪,ok
测试二:启动三个eureka注册中心,启动带hystrix(服务熔断)的服务提供者8004,启动hystrixDashboard   用dashboard来监控微服务8004
   访问 http://localhost:8004/user/list            8004正常启动
   访问 http://localhost:8004/hystrix.stream       出现ping
   豪猪哥页面  输入http://localhost:8004/hystrix.stream,dela栏位输入2000ms,title栏位输入demo001,点击monitor stream ,出现图像化界面 

九 Zuul服务网关

网关作用:
	服务路由
	超时处理
	熔断处理
	限流控制
	日志记录
	灰度发布
	负载均衡
	认证授权

1.新建模块cloud-zero-gateway 9527
2.pom
<dependencies>
    <!--gateway 网关依赖,内置webflux 依赖 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <!--eureka 客户端 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
</dependencies>
3.主启动类   @EnableDiscoveryClient  
4.yml  见最底下9.4
启动eureka  启动服务提供者  启动gateway 
http://localhost:8001/user/selectUserById                   能访问
http://gateway.com:9527/USER-PROVIDER/user/selectUserById   通过路由也能方法  (网关 + 微服务名称 + 微服务里面的访问路径)
把访问路径中的 USER-PROVIDER(微服务名称) 自定义
9527模块的yml文件spring添加如下  
spring:
 cloud:
    gateway:
      discovery:
        locator:
          enabled: true
      routes:
        #system 模块
        - id: cloud-zero-user
          uri: lb://USER-PROVIDER
          predicates:
            - Path=/test/**
          filters:
            - StripPrefix=1

十 Config 配置中心

github上传配置文件步骤
1.在github新建仓库cloud-zero-config并clone到本地    
2.在文件夹cloud-zero-config新建application.yml并提交到gitHub,注意文件另存为utf-8  

1.新建模块 cloud-zero-config2
2.pom
3.yml
4.主启动类加注解 @EnableConfigServer
测试:http://127.0.0.1:3344/application-dev.yml 
     http://127.0.0.1:3344/application-test.yml (最后面的application-test.yml有五种写法)

十一 SpringCloud GateWay 网关

1.pom引入依赖

//和springboot项目大致相同, 只是不需要spring-boot-starter-web并且网关的版本为2.2.1
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.4.RELEASE</version>
    </parent>

    <dependencies>
        <!-- nacos注册中心 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>2.2.4.RELEASE</version>
        </dependency>
        <!--Nacos配置中心-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            <version>2.2.4.RELEASE</version>
        </dependency>
         <!--gateway网关-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>

    </dependencies>

2.配置路由 spring.cloud.gateway

2.1 yml方式配置路由
server:
  port: 8089

spring:
  application:
    name: gateway

  cloud:
    gateway:
      discovery:
        locator:          
          enabled: true  #1.默认为false,设为true开启通过微服务创建路由的功能,既可以通过微服务名访问服务
      enabled: true    #      是否开启网关
      routes:
        
        - id: mock  #id自定义
          uri: lb://mock  #本来是localhost:8001,换成被调用方微服务名称  
        //uri: http://energy-cloud-pay-gateway-enetest.local.evota.com  或者直接域名
          predicates:
            - Path=/mock/**

    nacos:
      discovery:
       server-addr: localhost:8848

2.2 硬编码方式配置路由

在这里插入图片描述

配置路由里面的predicete详解

匹配访问请求
在这里插入图片描述

1.after:   //yml配置:- After=2020-02-21   
2.before      
3.between
4.cookies  // yml配置:-cookie=userName,zzyy  测试路径:localhost:9527/user/get --cookie="userName=zzyy"
5.headers     
6.host     // yml配置:- host=**.atguigu.com  测试路径:localhost:9527/user/get --H "Host:news.atguigu.com"
7.method   //- method=get
8.path    //- Path=/api/**
9.query   //- Query=userName,\d+   要有参数名userName并且值要为整数
10.remoteAddr         
11.weight route

网关过滤器,

拦截请求做额外处理

1.Spring Cloud GateWay的生命周期
pre和Post:业务逻辑之前和业务逻辑之后,类似与SpringAop的前置通知和后置通知

2.种类
Gateway FilterGlobal Filter (单一和全局)

3.自定义过滤器
  a.实现方式:implements Global Fileter,Orderes
  b.能干嘛:全局日志配置,统一网关鉴权

在这里插入图片描述

概览

在这里插入图片描述
5.2 消费者pom

  <dependencies>
        <!--eureka 客户端 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!-- SpringBoot Web容器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--api模块-->
        <dependency>
            <groupId>com.wind</groupId>
            <artifactId>cloud-zero-api</artifactId>
            <version>${project.version}</version>
        </dependency>
        <!-- spring-boot-devtools -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional> <!-- 表示依赖不会传递 -->
        </dependency>
    </dependencies>
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <configuration>
                    <delimiters>@</delimiters>
                    <useDefaultDelimiters>false</useDefaultDelimiters>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork> <!-- 如果没有该配置,devtools不会生效 -->
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

5.3 消费者的yml

server:
  port: 80

spring:
  application:
    name: user-consumer

eureka:
  client: # 客户端注册进eureka服务列表内
    service-url:
      defaultZone:  http://eureka7001.com:7001/eureka,
                    http://eureka7002.com:7002/eureka,
                    http://eureka7003.com:7003/eureka   #//是7001里面的defaultZone的地址
  instance:
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
    prefer-ip-address: true


info:
  app.name: consumer
  version: 20200317

5.4 ConfigBean

@Configuration
public class ConfigBean{
    @Bean
    //@LoadBalanced 需要负载均衡加此注解
    public RestTemplate getRestTemplate(){
    	return new RestTemplate();
    }
}

5.5 consumerController

@RestController
@RequestMapping("user")
public class ConsumerUserController{
    private static final String REST_URL_PREFIX = "http://localhost:8001";
     /**
     * 使用 使用restTemplate访问restful接口非常的简单粗暴无脑。 (url, requestMap,
     * ResponseBean.class)这三个参数分别代表 REST请求地址、请求参数、HTTP响应转换被转换成的对象类型。
     */
    @Autowired
    private RestTemplate  restTemplate;
    
    @RequestMapping(value = "add")
    public boolean add(User user){
       return restTemplate.postForObject(REST_URL_PREFIX + "/user/add", user, Boolean.class);
    }

    @RequestMapping(value = "get/{id}")
    public User get(@PathVariable("id") Long id){
       return restTemplate.getForObject(REST_URL_PREFIX + "/user/get/" + id, User.class);
    }

     @SuppressWarnings("unchecked")
     @RequestMapping(value = "list")
     public List<User> list(){
         return restTemplate.getForObject(REST_URL_PREFIX + "/user/list", List.class);
     }

    // 测试@EnableDiscoveryClient,消费端可以调用服务发现
    @RequestMapping(value = "discovery")
     public Object discovery(){
        return restTemplate.getForObject(REST_URL_PREFIX + "/user/discovery", Object.class);
     }
}

6.2 多个服务提供者的pom

<packaging>jar</packaging>
<dependencies>
    <dependency>
        <groupId>com.wind</groupId>
        <artifactId>cloud-zero-api</artifactId>
        <version>${project.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
    </dependency>

    <!--eureka客户端依赖-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>

    <!--监控依赖-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
</dependencies>

6.4 MySelfRule 负载均衡自定义算法
类加@Configuration 方法加@Bean

//第一种  Ribbon提供的
@Configuration
public class MySelfRule {
   @Bean
   public IRule diy(){
      return new RoundRobinRule();
   }
}
//第二种  自定义  比第一种多一个文件
@Configuration
public class MySelfRule{ 
    @Bean
    public IRule myRule(){
        return new MyRandomRule();
    }
}
public class MyRandomRule extends AbstractLoadBalancerRule{
    // total = 0 // 当total==5以后,我们指针才能往下走,
    // index = 0 // 当前对外提供服务的服务器地址,
    // total需要重新置为零,但是已经达到过一个5次,我们的index = 1
    // 分析:我们5次,但是微服务只有8001 8002 两台,OK?
    //
    private int total        = 0; // 总共被调用的次数,目前要求每台被调用5次
    private int currentIndex = 0; // 当前提供服务的机器号
    public Server choose(ILoadBalancer lb, Object key){
        if (lb == null){
            return null;
        }
        Server server = null;
        while (server == null){
            if (Thread.interrupted()){
                return null;
            }
            List<Server> upList = lb.getReachableServers();
            List<Server> allList = lb.getAllServers();
            int serverCount = allList.size();
            if (serverCount == 0){
               return null;
            }
            if (total < 5){
            	server = upList.get(currentIndex);
                total++;
            }else{
                total = 0;
                currentIndex++;
                if (currentIndex >= upList.size()){
                     currentIndex = 0;
                }
            }
            if (server == null){
                Thread.yield();
                continue;
            }
            if (server.isAlive()){
               return (server);
            }
             server = null;
            Thread.yield();
        }
        return server;
    }
    
    @Override
    public Server choose(Object key){
        return choose(getLoadBalancer(), key);
    }

    @Override
    public void initWithNiwsConfig(IClientConfig clientConfig){
    }

}

8.3 hystirxdashboard的pom

<dependencies>
    <!--api-->
    <dependency>
        <groupId>com.wind</groupId>
        <artifactId>cloud-zero-api</artifactId>
        <version>${project.version}</version>
    </dependency>
    <!--springboot-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--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>
    </dependency>
    <!--eureka客户端依赖-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>

    <!--监控依赖-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <!--hystrix-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
</dependencies>

测试一: 单独启动hystrixdashboard模块,http://localhost:9001/hystrix ,出现哥豪猪   ,ok

测试二

9.4 yml

server:
  port: 9527

spring:
  application:
    name:  cloud-zero-gateway
  devtools:
    restart:
      enabled: true
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
      routes:
        #system 模块
        - id: cloud-zero-user
          uri: lb://cloud-zero-user
          predicates:
            - Path=/serve-user/**
          filters:
            - StripPrefix=1

eureka:
  client: # 客户端注册进eureka服务列表内
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka,
                   http://eureka7002.com:7002/eureka,
                   http://eureka7003.com:7003/eureka  #//是7001里面的defaultZone的地址
  instance:
    instance-id:  ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
    prefer-ip-address: true


info:
  app.name: cloud-zero-gateway
  company.name: www.zmrit.com
  build.artifactId: aaa
  build1.version:  bbb
  build12.version2: ccc
  test.test: aaa

10.2.POM

<dependencies>
        <!--配置中心 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>
        <!--web 模块 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <!--排除tomcat依赖 -->
                <exclusion>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                    <groupId>org.springframework.boot</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--undertow容器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-undertow</artifactId>
        </dependency>
        <!-- spring-boot-devtools -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional> <!-- 表示依赖不会传递 -->
        </dependency>
    </dependencies>


    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork> <!-- 如果没有该配置,devtools不会生效 -->
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

10.3 yml

//配置中心3344的yml文件
server:
  port: 3344

spring:
  application:
    name: cloud-zero-config
  # 配置中心
  cloud:
    config:
      server:
        git:
          # 修改成你自己的git仓库
          uri:   https://github.com/piaoransheng/cloud-zero-config.git

//上传到gitHub上的文件
spring:
  profiles:
    active: dev
---
spring:
  profiles: dev     #开发环境
  application: 
    name: cloud-zero-config-dev
---
spring:
  profiles: test   #测试环境
  application: 
    name: cloud-zero-config-test
#  请保存为UTF-8格式

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
尚硅谷是一个教育机构,提供关于Spring Cloud的培训课程。Spring Cloud是一个分布式微服务架构的解决方案,它提供了一系列的组件和工具,用于构建和管理微服务应用程序。其中包括Spring Cloud Gateway,它是一个基于Spring Framework的API网关,用于处理和路由请求。你可以在Spring Cloud官方文档中找到关于Spring Cloud Gateway的详细信息。\[1\] 此外,Spring Cloud还与其他一些微服务平台和注册中心集成,如京东微服务平台、阿里微服务平台和京东物流服务。Spring Cloud使用注解来代替XML文件进行配置,并提供了父工程来管理各个模块的依赖关系。\[2\] 在注册中心方面,Spring Cloud支持多种选择,包括Nacos。Nacos是一个开源的动态服务发现、配置和服务管理平台,它可以作为Spring Cloud应用程序的注册中心。你可以在Nacos官方网站上找到更多关于Nacos的信息。\[3\] 总结起来,尚硅谷提供关于Spring Cloud的培训课程,Spring Cloud是一个分布式微服务架构的解决方案,它与多个微服务平台和注册中心集成,并使用注解进行配置。其中,Nacos是一个常用的注册中心选择之一。 #### 引用[.reference_title] - *1* *3* [尚硅谷SpringCloud(笔记仅供个人参考)](https://blog.csdn.net/qq_54726480/article/details/125370866)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [尚硅谷-Spring Cloud](https://blog.csdn.net/wa2661391317/article/details/126166867)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

飘然生

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

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

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

打赏作者

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

抵扣说明:

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

余额充值