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,
PRIMARY KEY (id
)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4;
INSERT INTO
user
(id
,phone
,pwd
,sex
,img
,create_time
,role
,username
,
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,无需重启服务,直接测试
测试结果