Spring Cloud Alibaba入门搭建

环境准备

建库建表

  • 创建cloud_video库,在cloud_video库下创建video表并初始化数据

CREATE TABLE video (
id int unsigned NOT NULL AUTO_INCREMENT,
title varchar(524) DEFAULT NULL COMMENT ‘视频标题’,
summary varchar(1026) DEFAULT NULL COMMENT ‘概述’,
cover_img varchar(524) DEFAULT NULL COMMENT ‘封面图’,
price int DEFAULT NULL COMMENT ‘价格,分’,
create_time datetime DEFAULT NULL COMMENT ‘创建时间’,
point double(11,2) DEFAULT ‘8.70’ COMMENT ‘默认8.7,最高10分’,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=48 DEFAULT CHARSET=utf8;

INSERT INTO video (id, title, summary, cover_img, price, create_time, point)
VALUES
(30, ‘java’, ‘java核心卷’, ‘222’, 3980, ‘2021-06-24 22:14:00’, 9.10),
(40, ‘oracle’, ‘从入门到精通’, ‘222’, 5980, ‘2021-01-18 22:14:00’, 9.10),
(41, ‘vue’, ‘vue入门’, ‘222’, 4880, ‘2021-01-10 22:14:00’, 8.70),
(45, ‘docker’, ‘docker实战’, ‘222’, 5980, ‘2021-01-10 22:14:00’, 9.30),
(46, ‘新版javase零基础到高级教程小白自学编程’, ‘111’, ‘222’, 3980, ‘2021-01-24 22:14:00’, 8.80);

  • 创建cloud_user数据库,在cloud_user库下创建user表

CREATE TABLE user (
id int(11) unsigned NOT NULL AUTO_INCREMENT,
phone varchar(32) DEFAULT NULL,
pwd varchar(128) DEFAULT NULL,
sex int(2) DEFAULT NULL,
img varchar(128) DEFAULT NULL,
create_time datetime DEFAULT NULL,
role int(11) DEFAULT NULL COMMENT ‘1是普通用户,2是管理员’,
username varchar(128) DEFAULT NULL,
wechat varchar(128) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4;

INSERT INTO user (id, phone, pwd, sex, img, create_time, role, username, wechat)
VALUES
(1, ‘123’, ‘666’, 1, ‘csdn.net’, ‘2021-09-09 00:00:00’, 1, ‘jack’, ‘222’),
(2, ‘2323432’, ‘794666918’, 1, ‘wwwww’, ‘2020-05-20 04:54:01’, 1, ‘rose’, ‘333’),
(3, ‘2323432’, ‘xdclass-lw’, 1, ‘wwwww’, ‘2020-05-20 04:54:42’, 1, ‘luoyu’, ‘444’),
(4, ‘2323432’, ‘3232323’, 1, ‘wwwww’, ‘2020-05-20 04:55:07’, 1, ‘laozhang’, ‘555’);

  • 创建cloud_order库并新建video_order表

CREATE TABLE video_order (
id int(11) unsigned NOT NULL AUTO_INCREMENT,
out_trade_no varchar(64) DEFAULT NULL COMMENT ‘订单唯一标识’,
state int(11) DEFAULT NULL COMMENT ‘0表示未支付,1表示已支付’,
create_time datetime DEFAULT NULL COMMENT ‘订单生成时间’,
total_fee int(11) DEFAULT NULL COMMENT ‘支付金额,单位分’,
video_id int(11) DEFAULT NULL COMMENT ‘视频主键’,
video_title varchar(256) DEFAULT NULL COMMENT ‘视频标题’,
video_img varchar(256) DEFAULT NULL COMMENT ‘视频图片’,
user_id int(12) DEFAULT NULL COMMENT ‘用户id’,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=42 DEFAULT CHARSET=utf8;

创建聚合工程

	nap-common
	nap-order
	nap-user
	nap-video

初始化项目,引入依赖

聚合工程下的pon.xml文件

<?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>

    <groupId>com.ht</groupId>
    <artifactId>nap-cloud</artifactId>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>nap-video</module>
        <module>nap-order</module>
        <module>nap-user</module>
        <module>nap-common</module>
    </modules>
    <packaging>pom</packaging>
    <properties>
        <java.version>1.8</java.version>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.3.3.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR8</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.2.1.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.1.2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork>
                    <addResources>true</addResources>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

nap-common下的pom.xml

<?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>nap-cloud</artifactId>
        <groupId>com.ht</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>nap-common</artifactId>

</project>

nap-order的pom文件,yml文件

<?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>nap-cloud</artifactId>
        <groupId>com.ht</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>nap-order</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.ht</groupId>
            <artifactId>nap-common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    </dependencies>

</project>

yml

server:
  port: 9000
spring:
  application:
    name: nap-order
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/cloud_order?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
    username: nap
    password: nap123
mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true

nap-user的pom,yml

<?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>nap-cloud</artifactId>
        <groupId>com.ht</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>nap-user</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.ht</groupId>
            <artifactId>nap-common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    </dependencies>

</project>

yml

server:
  port: 9001
spring:
  application:
    name: nap-user
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/cloud_user?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
    username: nap
    password: nap123
mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true

nap-video的pom,yml

<?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>nap-cloud</artifactId>
        <groupId>com.ht</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>nap-video</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.ht</groupId>
            <artifactId>nap-common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    </dependencies>

</project>

yml

server:
  port: 9002
spring:
  application:
    name: nap-video
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/cloud_video?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
    username: nap
    password: nap123
mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true

编辑模块的基础代码

nap-video

创建包目录
在这里插入图片描述
代码如下
controller

package com.ht.controller;

import com.ht.service.VideoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/video")
public class VideoController {
    @Autowired
    private VideoService videoService;
    @RequestMapping("/getVideo")
    public Object getVideo(int videoId) {
        System.out.println("enter videoController");
        return videoService.getVideo(videoId);
    }
}

service

package com.ht.service;

import com.ht.entity.Video;

public interface VideoService {
    Video getVideo(int videoId);
}

serviceImpl

package com.ht.service.impl;

import com.ht.entity.Video;
import com.ht.mapper.VideoMapper;
import com.ht.service.VideoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class VideoServiceImpl implements VideoService {
    @Autowired
    private VideoMapper videoMapper;
    @Override
    public Video getVideo(int videoId) {
        return videoMapper.getVideo(videoId);
    }
}

mapper

package com.ht.mapper;

import com.ht.entity.Video;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;

@Repository
public interface VideoMapper {
    @Select("select * from video where id=#{videoId}")
    Video getVideo(@Param("videoId") int videoId);
}

启动类


import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.ht.mapper")
public class VideoApplication {
    public static void main(String[] args) {
        SpringApplication.run(VideoApplication.class,args);
    }
}

启动项目并测试

在这里插入图片描述

服务注册发现:Nacos

启动

将nacos安装包上传至虚拟机并解压,进入到bin目录,单机启动
sh startup.sh -m standalone

访问

http://192.1.1.101:8848/nacos
默认用户密码都是nacos

在这里插入图片描述

项目中配置nacos

  • pom文件引入依赖
<dependency>
           <groupId>com.alibaba.cloud</groupId>
           <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
       </dependency>
  • yml文件配置注册中心地址
spring:
 application:
   name: nap-video
 datasource:
   driver-class-name: com.mysql.cj.jdbc.Driver
   url: jdbc:mysql://127.0.0.1:3306/cloud_video?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
   username: nap
   password: nap123
 cloud:
   nacos:
     discovery:
       server-addr: 192.1.1.101:8848
  • 启动类增加注解
@EnableDiscoveryClient
  • 启动测试
    在这里插入图片描述

负载均衡,服务调用:OpenFeign

nap-order通过openfeign调用nap-video

  • 将nap-order工程也引入nacos注册中心,具体步骤参照nap-video模块
  • 引入openfeign依赖(nap-order工程)
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
  • nap-order工程目录
    在这里插入图片描述
  • controller代码
package com.ht.controller;

import com.ht.entity.Order;
import com.ht.entity.Video;
import com.ht.service.VideoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/order")
public class OrderController {
    @Autowired
    private VideoService videoService;
    @RequestMapping("/findByVideoId")
    public Object findByVideoId(int videoId){
        Video video=videoService.getVideo(videoId);
        Order order =new Order();
        order.setVideoId(video.getId());
        order.setVideoTitle(video.getTitle());
        order.setVideoImg(video.getCoverImg());
        return order;
    }
}

  • servie代码(这里的service作为nap-video的service层的客户端)
package com.ht.service;

import com.ht.entity.Video;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@FeignClient(name = "nap-video")
public interface VideoService {
    @GetMapping(value = "/video/getVideo")
    public Video getVideo(@RequestParam("videoId") int videoId);
}

  • 测试结果
    在这里插入图片描述

服务限流降级:Sentinel

搭建sentinel控制台

  • 将sentinel对应版本的jar包上传至服务器
  • 执行命令
nohup java -jar sentinel-xxxx.jar &
默认启动的是8080端口

登录sentinel控制台
用户名和密码默认都是sentinel

http://192.1.1.101:8080

在这里插入图片描述

项目中配置sentinel

  • 在nap-video与nap-order中引入sentinel依赖
<dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
  • 配置nap-video与nap-order的yml文件
server:
  port: 9004
spring:
  application:
    name: nap-video
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/cloud_video?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
    username: nap
    password: nap123
  cloud:
    nacos:
      discovery:
        server-addr: 192.1.1.101:8848
    sentinel:
      transport:
        dashboard: 192.1.1.101:8080
        port: 9997
mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true
server:
  port: 9000
spring:
  application:
    name: nap-order
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/cloud_order?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
    username: nap
    password: nap123
  cloud:
    nacos:
      discovery:
        server-addr: 192.1.1.101:8848
    sentinel:
      transport:
        dashboard: 192.1.1.101:8080
        port: 9998
mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true
  • 由于Sentinel是懒加载模式,所以需要访问微服务后才会在控制台出现,所以启动服务后,我们需要先需要使用posman发几次查询,然后刷新sentinel控制台
    (我在idea里启动了2个nap-video,所以sentinel控制台中会显示2个nap-video服务)
    在这里插入图片描述

QPS限流

  • 登录sentinel控制台,在对应要进行的限流的服务进行如下设置
    在这里插入图片描述在这里插入图片描述

  • 测试限流
    在这里插入图片描述

自定义降级业务

  • 实现BlockExceptionHandler接口
    在nap-order中新建NapBlockExceptionHandler类实现BlockExceptionHandler接口
package com.ht.handler;

import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.system.SystemBlockException;
import com.alibaba.fastjson.JSON;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

@Component
public class NapBlockExceptionHandler implements BlockExceptionHandler {
   @Override
   public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws Exception {
       Map map =new HashMap();
       if(e instanceof FlowException){
           map.put("code","-1");
           map.put("msg","限流异常");
       }else if(e instanceof DegradeException){
           map.put("code","-2");
           map.put("msg","降级异常");
       }else if(e instanceof SystemBlockException){
           map.put("code","-3");
           map.put("msg","系统异常");
       }
       httpServletResponse.setStatus(200);
       httpServletResponse.setHeader("content-type","application/json;charset=UTF-8");
       httpServletResponse.getWriter().write(JSON.toJSONString(map));
   }
}

  • 执行测试,此时QPS限流异常返回了自定义信息
    在这里插入图片描述

sentinel整合openfeign配置

nap-order中的controller中findByVideoId方法会调用nap-video中的getVideo方法,如果nap-video服务停掉,我们可以使用容错类来返回一个默认的视频信息。

  • 开启Feign对Sentinel的支持
    编辑nap-order中的yml文件
feign:
  sentinel:
    enabled: true
  • 创建VideoServiceFallback类
package com.ht.service.fallback;

import com.ht.entity.Video;
import com.ht.service.VideoService;
import org.springframework.stereotype.Service;

@Service
public class VideoServiceFallback implements VideoService {
    @Override
    public Video getVideo(int videoId) {
        Video v =new Video();
        v.setTitle("fallback video");
        return v;
    }
}

  • 停掉nap-video服务,测试
    在这里插入图片描述

服务网关:SpringCloud Gateway

新建gateway网关工程nap-api

  • 引入依赖
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
  • 配置yml文件
server:
  port: 8888
spring:
  application:
    name: nap-api
  cloud:
    nacos:
      discovery:
        server-addr: 192.1.1.101:8848
    gateway:
      routes: #数组形式
        - id: nap-order #路由唯一标识
          uri: lb://nap-order #想要转发到的地址,从nacos注册中心上拉取,lb:负载均衡轮询
          predicates: #断言 配置哪个路径才转发
            - Path=/nap-order/**
          filters:
            - StripPrefix=1 #去掉第一层前缀
        - id: nap-video
            uri: lb://nap-video
            predicates:
              - Path=/nap-video/**
            filters:
              - StripPrefix=1
      discovery:
        locator:
          enabled: true

  • 启动类
package com.ht;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class ApiApplication {
    public static void main(String[] args) {
        SpringApplication.run(ApiApplication.class,args);
    }
}

  • 测试
    在这里插入图片描述

网关过滤器分类

  • 局部过滤器GatewayFilter:应用在某个路由上,每个过滤器工厂都对应一个实现类,并且这些类的名称必须以 GatewayFilterFactory 结尾
  • 全局过滤器:作用全部路由上
  • 内置很多全局过滤器,顶级接口 GlobalFilter
  • 自定义全局过滤器
package com.ht.filter;

import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
public class UserGlobalFilter implements GlobalFilter, Ordered {
   @Override
   public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
       String token=exchange.getResponse().getHeaders().getFirst("token");
       if(StringUtils.isBlank(token)){
           exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
           exchange.getResponse().setComplete();
       }
       return chain.filter(exchange);
   }

   @Override
   public int getOrder() {
       return 0;
   }
}

链路追踪:Sleuth+Zipkin

  • 启动zipkin控制台
    将zip对应版本的jar包上传至服务器
nohup java -jar zipkin-xxxx.jar &
默认端口是9411

在这里插入图片描述

  • 引入依赖(nap-api,nap-order,nap-video)
<dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-starter-sleuth</artifactId>
       </dependency>
       <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-starter-zipkin</artifactId>
       </dependency>
  • 配置yml文件(nap-api,nap-order,nap-video)
server:
 port: 8888
spring:
 application:
   name: nap-api
 cloud:
   nacos:
     discovery:
       server-addr: 192.1.1.101:8848
   gateway:
     routes: #数组形式
       - id: nap-order #路由唯一标识
         uri: lb://nap-order #想要转发到的地址,从nacos注册中心上拉取,lb:负载均衡轮询
         predicates: #断言 配置哪个路径才转发
           - Path=/nap-order/**
         filters:
           - StripPrefix=1 #去掉第一层前缀
       - id: nap-video
         uri: lb://nap-video
         predicates:
           - Path=/nap-video/**
         filters:
           - StripPrefix=1
     discovery:
       locator:
         enabled: true
 sleuth:
   sampler:
     rate: 1
 zipkin:
   base-url: http://192.1.1.101:9411/
   discovery-client-enabled: false
   enabled: true

  • 启动项目,执行测试
    在这里插入图片描述

微服务链路追踪系统Zipkin持久化配置

  • 创建zipkin持久化数据库cloud_zipkin
CREATE TABLE IF NOT EXISTS zipkin_spans (
  `trace_id_high` BIGINT NOT NULL DEFAULT 0 COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit',
  `trace_id` BIGINT NOT NULL,
  `id` BIGINT NOT NULL,
  `name` VARCHAR(255) NOT NULL,
  `remote_service_name` VARCHAR(255),
  `parent_id` BIGINT,
  `debug` BIT(1),
  `start_ts` BIGINT COMMENT 'Span.timestamp(): epoch micros used for endTs query and to implement TTL',
  `duration` BIGINT COMMENT 'Span.duration(): micros used for minDuration and maxDuration query',
  PRIMARY KEY (`trace_id_high`, `trace_id`, `id`)
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;
 
ALTER TABLE zipkin_spans ADD INDEX(`trace_id_high`, `trace_id`) COMMENT 'for getTracesByIds';
ALTER TABLE zipkin_spans ADD INDEX(`name`) COMMENT 'for getTraces and getSpanNames';
ALTER TABLE zipkin_spans ADD INDEX(`remote_service_name`) COMMENT 'for getTraces and getRemoteServiceNames';
ALTER TABLE zipkin_spans ADD INDEX(`start_ts`) COMMENT 'for getTraces ordering and range';
 
CREATE TABLE IF NOT EXISTS zipkin_annotations (
  `trace_id_high` BIGINT NOT NULL DEFAULT 0 COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit',
  `trace_id` BIGINT NOT NULL COMMENT 'coincides with zipkin_spans.trace_id',
  `span_id` BIGINT NOT NULL COMMENT 'coincides with zipkin_spans.id',
  `a_key` VARCHAR(255) NOT NULL COMMENT 'BinaryAnnotation.key or Annotation.value if type == -1',
  `a_value` BLOB COMMENT 'BinaryAnnotation.value(), which must be smaller than 64KB',
  `a_type` INT NOT NULL COMMENT 'BinaryAnnotation.type() or -1 if Annotation',
  `a_timestamp` BIGINT COMMENT 'Used to implement TTL; Annotation.timestamp or zipkin_spans.timestamp',
  `endpoint_ipv4` INT COMMENT 'Null when Binary/Annotation.endpoint is null',
  `endpoint_ipv6` BINARY(16) COMMENT 'Null when Binary/Annotation.endpoint is null, or no IPv6 address',
  `endpoint_port` SMALLINT COMMENT 'Null when Binary/Annotation.endpoint is null',
  `endpoint_service_name` VARCHAR(255) COMMENT 'Null when Binary/Annotation.endpoint is null'
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;
 
ALTER TABLE zipkin_annotations ADD UNIQUE KEY(`trace_id_high`, `trace_id`, `span_id`, `a_key`, `a_timestamp`) COMMENT 'Ignore insert on duplicate';
ALTER TABLE zipkin_annotations ADD INDEX(`trace_id_high`, `trace_id`, `span_id`) COMMENT 'for joining with zipkin_spans';
ALTER TABLE zipkin_annotations ADD INDEX(`trace_id_high`, `trace_id`) COMMENT 'for getTraces/ByIds';
ALTER TABLE zipkin_annotations ADD INDEX(`endpoint_service_name`) COMMENT 'for getTraces and getServiceNames';
ALTER TABLE zipkin_annotations ADD INDEX(`a_type`) COMMENT 'for getTraces and autocomplete values';
ALTER TABLE zipkin_annotations ADD INDEX(`a_key`) COMMENT 'for getTraces and autocomplete values';
ALTER TABLE zipkin_annotations ADD INDEX(`trace_id`, `span_id`, `a_key`) COMMENT 'for dependencies job';
 
CREATE TABLE IF NOT EXISTS zipkin_dependencies (
  `day` DATE NOT NULL,
  `parent` VARCHAR(255) NOT NULL,
  `child` VARCHAR(255) NOT NULL,
  `call_count` BIGINT,
  `error_count` BIGINT,
  PRIMARY KEY (`day`, `parent`, `child`)
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;
  • 启动zipkin
nohup java -jar zipkin-server-2.12.9-exec.jar --STORAGE_TYPE=mysql --MYSQL_HOST=192.168.42.62 --MYSQL_TCP_PORT=3306 --MYSQL_DB=cloud_zipkin --MYSQL_USER=nap --MYSQL_PASS=nap123 &
  • 测试

在这里插入图片描述

在这里插入图片描述

分布式配置中心:Nacos

  • nap-order中添加依赖
<dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
  • 创建bootstrap.yml
spring:
  application:
    name: nap-order
  cloud:
    nacos:
      config:
        server-addr: 192.1.1.101:8848 #Nacos配置中心地址
        file-extension: yaml #文件拓展格式
  profiles:
    active: dev
  • 在nacos控制台上的配置列表中创建nap-order-dev.yaml配置
    Data Id:nap-order-dev.yaml
    配置格式: yaml
    将项目中application.yml文件内容拷贝到配置内容中,然后点击发布
    在这里插入图片描述
  • 将nap-order项目中的application.yml文件内容都注释掉,启动服务。如果成功启动,说明配置成功
  • 编辑nap-order-dev.yaml
    我这里在项目中测试通过配置动态改变通讯的ip和port
esb:
  ip: 10.172.92.145
  port: 21198
  • 修改nap-order的controller类
    加入esbIp和esbPort属性
    加入@RefreshScope注解(动态刷新)
package com.ht.controller;

import com.ht.entity.Order;
import com.ht.entity.Video;
import com.ht.service.VideoService;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/order")
@RefreshScope
public class OrderController {
    @Autowired
    private VideoService videoService;
    @Value("${esb.ip}")
    private String esbIp;
    @Value("${esb.port}")
    private String esbPort;
    @RequestMapping("/findByVideoId")
    public Object findByVideoId(int videoId){
        Video video=videoService.getVideo(videoId);
        Order order =new Order();
        order.setVideoId(video.getId());
        order.setVideoTitle(video.getTitle());
        order.setVideoImg(esbIp);
        order.setTotalFee(Integer.parseInt(esbPort));
        return order;
    }
    @RequestMapping("/list")
    public Object list(HttpServletRequest request){
        Map map =new HashMap<>();

        /*try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }*/
        map.put("port",request.getServerPort());
        map.put("title1","111");
        map.put("title2","222");
        return map;
    }
}

  • 启动服务测试
    在这里插入图片描述
  • 在nacos控制台上编辑nap-order-dev.yaml,修改esb下的ip和端口,修改成192.168.0.1和8001,无需重启服务,直接测试
    测试结果
    在这里插入图片描述
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值