springCloud

1.搭建父工程

使用springboot搭建

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9h4OGfXv-1661184648520)(C:\Users\20372\AppData\Roaming\Typora\typora-user-images\image-20220821114909096.png)]

在pom依赖中导入依赖

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

4.0.0

pom

eureka-server

org.springframework.boot

spring-boot-starter-parent

2.2.11.RELEASE

org.ymh

springCloud

1.0-SNAPSHOT

8

8

UTF-8

UTF-8

Hoxton.SR12

org.springframework.cloud

spring-cloud-dependencies

${spring-cloud.version}

pom

import

2.搭建eureka-server

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

springCloud

org.ymh

1.0-SNAPSHOT

4.0.0

eureka-server

8

8

org.springframework.cloud

spring-cloud-starter-netflix-eureka-server

yml文件

# eureka 配置

# eureka 一共有4部分 配置

# 1. dashboard:eureka的web控制台配置

# 2. server:eureka的服务端配置

# 3. client:eureka的客户端配置

# 4. instance:eureka的实例配置

server:

port: 8761

eureka:

instance:

hostname: localhost # 主机名

client:

service-url:

defaultZone: http://localhost:8761/eureka # http://139.155.8.246:8763/eureka, http://192.168.11.128:8762/eureka # eureka服务端地址,将来客户端使用该地址和eureka进行通信

register-with-eureka: false # 是否将自己的路径 注册到eureka上。eureka server 不需要的,eureka provider client 需要

fetch-registry: false # 是否需要从eureka中抓取路径。eureka server 不需要的,eureka consumer client 需要

spring:

application:

name: eureka-server

主启动类

package com.code;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication

@EnableEurekaServer

public class EurekaServerApplication {

public static void main(String[] args) {

SpringApplication.run(EurekaServerApplication.class, args);

}

}

3.搭建euraka-provider

pom文件

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

springCloud

org.ymh

1.0-SNAPSHOT

4.0.0

eureka-provider

8

8

org.springframework.cloud

spring-cloud-starter-netflix-eureka-client

org.springframework.boot

spring-boot-starter-web

yml文件

server:

port: 8001

eureka:

instance:

hostname: localhost # 主机名

client:

service-url:

defaultZone: http://localhost:8761/eureka # eureka服务端地址,将来客户端使用该地址和eureka进行通信

spring:

application:

name: eureka-provider # 设置当前应用的名称。将来会在eureka中Application显示。将来需要使用该名称来获取路径

启动类

package com.code;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication

@EnableEurekaClient

public class EurekaProviderApplication {

public static void main(String[] args) {

SpringApplication.run(EurekaProviderApplication.class, args);

}

}

eureka-consumer使用ribbon

a. 导入依赖

org.springframework.cloud

spring-cloud-starter-netflix-ribbon

b.负载均衡策略 也可以在配置文件中配置

import com.netflix.loadbalancer.IRule;

import com.netflix.loadbalancer.RoundRobinRule;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

/**

* ribbion负载均策略

*/

@Configuration

public class MyRule {

@Bean

public IRule iRule() {

return new RoundRobinRule();

}

}

c. controller中

import com.code.domain.Goods;

import com.code.feign.GoodsFeign;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.cloud.client.discovery.DiscoveryClient;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.PathVariable;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import org.springframework.web.client.RestTemplate;

@RestController

@RequestMapping("/order")

public class OrderController {

@Autowired

private RestTemplate restTemplate;

//发现客户端

@Autowired

private DiscoveryClient discoveryClient;

@Autowired

private GoodsFeign goodsFeign;

@GetMapping("/add/{id}")

public Goods add(@PathVariable("id") int id) {

//业务逻辑

//1 查询商品

//2减库存

//3支付

//4 物流

//ribbin调用

String url = "http://EUREKA-PROVIDER/goods/findById/"+id;

System.out.println(url);

Goods goods = restTemplate.getForObject(url, Goods.class);

if(goods.getGoodId() == -1) {

//打日志

//提醒

}

return goods;

}

}

d. yml配置中添加

# 设置Ribbon的超时时间

ribbon:

ConnectTimeout: 1000 # 连接超时时间 默认1s

ReadTimeout: 3000 # 逻辑处理的超时时间 默认3s

e. 主启动类

import com.code.config.MyRule;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

import org.springframework.cloud.netflix.ribbon.RibbonClient;

import org.springframework.cloud.netflix.ribbon.RibbonClients;

import org.springframework.cloud.openfeign.EnableFeignClients;

@EnableEurekaClient

@SpringBootApplication

//@RibbonClient(name = "EUREKA-PROVIDER", configuration = MyRule.class)

@RibbonClients(value = {@RibbonClient(name = "EUREKA-PROVIDER", configuration = MyRule.class)})

public class ConsumerApplication {

public static void main(String[] args) {

SpringApplication.run(ConsumerApplication.class, args);

}

}

eureka-consumer使用feign

a. 导入依赖

org.springframework.cloud

spring-cloud-starter-openfeign

b. 编写feign接口

import com.code.config.FeignLogConfig;

import com.code.domain.Goods;

import org.springframework.cloud.openfeign.FeignClient;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.PathVariable;

@FeignClient(value = "EUREKA-PROVIDER", configuration = FeignLogConfig.class, fallback = GoodsFeignCallBack.class)

public interface GoodsFeign {

@GetMapping("goods/findById/{id}")

public Goods findById(@PathVariable("id") int id);

}

c. 主启动类上添加注解

@EnableFeignClients

import com.code.config.MyRule;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

import org.springframework.cloud.netflix.ribbon.RibbonClient;

import org.springframework.cloud.netflix.ribbon.RibbonClients;

import org.springframework.cloud.openfeign.EnableFeignClients;

@EnableEurekaClient

@SpringBootApplication

//@RibbonClient(name = "EUREKA-PROVIDER", configuration = MyRule.class)

@EnableFeignClients

@RibbonClients(value = {@RibbonClient(name = "EUREKA-PROVIDER", configuration = MyRule.class)})

public class ConsumerApplication {

public static void main(String[] args) {

SpringApplication.run(ConsumerApplication.class, args);

}

}

d. 开启feign日志 feign只支持debug级别的日志

yml中配置 #日志

logging:

level:

com.code: debug

日志配置类 import feign.Logger;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

@Configuration

public class FeignLogConfig {

@Bean

public Logger.Level level() {

return Logger.Level.FULL; //打印日志的详细程度

}

}

eureka-provider中使用服务降级、熔断、线程池隔离

a. 导入依赖

org.springframework.cloud

spring-cloud-starter-netflix-hystrix

b. 主启动类添加注解@EnableCircuitBreaker //开启Hystrix功能

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;

import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

import org.springframework.cloud.netflix.hystrix.EnableHystrix;

@SpringBootApplication

@EnableEurekaClient

@EnableCircuitBreaker //开启Hystrix功能

public class EurekaProviderApplication {

public static void main(String[] args) {

SpringApplication.run(EurekaProviderApplication.class, args);

}

}

服务方服务降级与熔断

import com.code.entity.Goods;

import com.code.service.GoodsService;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;

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.GetMapping;

import org.springframework.web.bind.annotation.PathVariable;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

@RestController

@RequestMapping("/goods")

@RefreshScope // 开启刷新功能

public class GoodsController {

@Autowired

GoodsService goodsService;

@Value("${server.port}")

private Integer port;

@Value("${ydlclass}")

private String str;

/**

提供方服务降级

1. 超时

2. 业务逻辑超时

3. 熔断在一定时间类失败次数达到阈值服务断开 过一段时间服务成半开启状态 当成功次数又达到阈值服务完全开启

*/

@GetMapping("findById/{id}")

@HystrixCommand(fallbackMethod = "findById_fallBack", commandProperties = {

//设置Hystrix的超时时间, 默认为1s

@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000"),

//监控时间 默认5000 毫秒

@HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds",value = "5000"),

//失败次数。默认20次

@HystrixProperty(name="circuitBreaker.requestVolumeThreshold",value = "20"),

//失败率 默认50%

@HystrixProperty(name="circuitBreaker.errorThresholdPercentage",value = "50")

})

public Goods findById(@PathVariable("id") int id){

Goods goods = goodsService.findById(id);

goods.setTitle(goods.getTitle()+"|端口号:"+port+"|"+str);

return goods;

}

/**

* 定义服务方降级方法

* 1 方法的返回值和原方法一样

* 2 方法参数和原方法一样

*/

public Goods findById_fallBack(int id) {

Goods goods = new Goods();

goods.setGoodId(-1);

goods.setTitle("provider提供方降级!");

goods.setPrice(-9.9);

goods.setStore(-10);

return goods;

}

}

全部配置文件yml

server:

port: 8000

eureka:

instance:

hostname: localhost

prefer-ip-address: true #是否将自己的Ip注册到eureka种,默认false 注册 主机名

ip-address: 127.0.0.1 #设置当前实例ip

#instance-id: 修改instance-id显示

instance-id: ${eureka.instance.ip-address}:${spring.application.name}:${server.port}

lease-renewal-interval-in-seconds: 30 #每一次eureka client 先eureka server发送心跳的时间间隔

lease-expiration-duration-in-seconds: 90 #如果90秒 eureka -server 没有eureka client 发送心跳包 注册书中删除注册

client:

service-url:

defaultZonezz: http://localhost:8761/eureka #,http://eureka-server1:8763/eureka # eureka服务端地址,将来客户端使用该地址和eureka进行通信

register-with-eureka: true #启动时是否将自己注册到eureka上

fetch-registry: true #是否需要从eureka种抓取数据

spring:

application:

name: eureka-provider #设置当前应用名称

zipkin:

base-url: http://localhost:9411/ # 设置zipkin的服务端路径

sleuth:

sampler:

probability: 1 # 采集率 默认 0.1 百分之十。

ydlclass: itymhLLLL9999888888尹明洪6667777

eureka-consumer中使用Hystrix

a. 由于feign中已经集成了Hystrix所以不需要在引入依赖

b. 在yml中配置、

# 开启feign对hystrix的支持

feign:

hystrix:

enabled: true

c. 编写feign接口的实现类服务消费方降级

import com.code.domain.Goods;

import org.springframework.stereotype.Component;

@Component

public class GoodsFeignCallBack implements GoodsFeign {

@Override

public Goods findById(int id) {

Goods goods = new Goods();

goods.setGoodId(-2);

goods.setTitle("调用方降级了!");

goods.setPrice(-5.5);

goods.setStore(-10);

return goods;

}

}

d.主启动类上添加注解@EnableFeignClients

import com.code.config.MyRule;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

import org.springframework.cloud.netflix.ribbon.RibbonClient;

import org.springframework.cloud.netflix.ribbon.RibbonClients;

import org.springframework.cloud.openfeign.EnableFeignClients;

@EnableEurekaClient

@SpringBootApplication

//@RibbonClient(name = "EUREKA-PROVIDER", configuration = MyRule.class)

@EnableFeignClients

@RibbonClients(value = {@RibbonClient(name = "EUREKA-PROVIDER", configuration = MyRule.class)})

public class ConsumerApplication {

public static void main(String[] args) {

SpringApplication.run(ConsumerApplication.class, args);

}

}

e. 在feign接口上注解添加 fallback = GoodsFeignCallBack.class

import com.code.config.FeignLogConfig;

import com.code.domain.Goods;

import org.springframework.cloud.openfeign.FeignClient;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.PathVariable;

@FeignClient(value = "EUREKA-PROVIDER", configuration = FeignLogConfig.class, fallback = GoodsFeignCallBack.class)

public interface GoodsFeign {

@GetMapping("goods/findById/{id}")

public Goods findById(@PathVariable("id") int id);

}

服务消费者yml

server:

port: 9000

eureka:

instance:

hostname: localhost # 主机名

client:

service-url:

defaultZone: http://localhost:8761/eureka #注册到eureka上

register-with-eureka: true

fetch-registry: true

spring:

application:

name: eureka-consumer #

# 设置Ribbon的超时时间

ribbon:

ConnectTimeout: 1000 # 连接超时时间 默认1s

ReadTimeout: 3000 # 逻辑处理的超时时间 默认3s

#日志

logging:

level:

com.code: debug

# 开启feign对hystrix的支持

feign:

hystrix:

enabled: true

getway网关

a. 导入依赖

org.springframework.cloud

spring-cloud-starter-netflix-eureka-client

org.springframework.cloud

spring-cloud-starter-gateway

b. 配置yml

server:

port: 80

spring:

application:

name: api-gateway-server

cloud:

# 网关配置

# 微服务名称配置

discovery:

locator:

enabled: true # 设置为true 请求路径前可以添加微服务名称

lower-case-service-id: true # 允许为小写

gateway:

# 路由配置:转发规则

routes: #集合。

# id: 唯一标识。默认是一个UUID

# uri: 转发路径

# predicates: 条件,用于请求网关路径的匹配规则

# filters:配置局部过滤器的

- id: eureka-provider

# 静态路由

#uri: http://localhost:8000

# 动态路由

uri: lb://eureka-PROVIDER

predicates:

- Path=/goods/**

filters:

- AddRequestParameter=username,zhangsan

- AddResponseHeader=ydl,ymh

- id: eureka-consumer

# uri: http://localhost:8001

uri: lb://eureka-CONSUMER

predicates:

- Path=/order/**

default-filters:

- AddResponseHeader=ydl,ymh

eureka:

client:

service-url:

defaultZone: http://localhost:8761/eureka

c. 主启动类

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication

public class Application {

public static void main(String[] args) {

SpringApplication.run(Application.class, args);

}

}

网关作用

路由过滤 内置局部 内置全局 自定义局部 自定义全局

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.http.server.ServletServerHttpRequest;

import org.springframework.http.server.reactive.ServerHttpRequest;

import org.springframework.http.server.reactive.ServerHttpResponse;

import org.springframework.stereotype.Component;

import org.springframework.web.server.ServerWebExchange;

import reactor.core.publisher.Mono;

import java.net.InetAddress;

import java.net.InetSocketAddress;

@Component

public class IpFilter implements GlobalFilter, Ordered {

//写业务逻辑

@Override

public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {

// 黑客ip,直接拒接

ServerHttpRequest request = exchange.getRequest();

ServerHttpResponse response = exchange.getResponse();

InetSocketAddress inetSocketAddress = request.getRemoteAddress();

String hostName = inetSocketAddress.getHostName();

System.out.println("HostName"+hostName);

InetAddress address = inetSocketAddress.getAddress();

String hostAddress = address.getHostAddress();

System.out.println("HostAddress"+hostAddress);

String hostName1 = address.getHostName();

System.out.println("hostname1"+hostName1);

if(hostAddress.equals("192.168.3.158")) {

//拒绝

response.setStatusCode(HttpStatus.UNAUTHORIZED);

return response.setComplete();

}

//走完了该到下一个过滤器了

return chain.filter(exchange);

}

//返回数值 数值越小越先执行

@Override

public int getOrder() {

return 0;

}

}

import org.springframework.cloud.gateway.filter.GatewayFilterChain;

import org.springframework.cloud.gateway.filter.GlobalFilter;

import org.springframework.core.Ordered;

import org.springframework.http.server.reactive.ServerHttpRequest;

import org.springframework.http.server.reactive.ServerHttpResponse;

import org.springframework.web.server.ServerWebExchange;

import reactor.core.publisher.Mono;

import java.net.URI;

public class UrlFilter implements GlobalFilter, Ordered {

@Override

public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {

// 黑客ip,直接拒接

ServerHttpRequest request = exchange.getRequest();

ServerHttpResponse response = exchange.getResponse();

URI uri = request.getURI();

String path = uri.getPath();

if(path.contains("goods/findGoodsById")){

//打日志

System.out.println("path危险");

}

return chain.filter(exchange);

}

@Override

public int getOrder() {

return 1;

}

}

spring-cloud配置中心与bus消息总线

a. 导入依赖

org.springframework.cloud

spring-cloud-config-server

org.springframework.cloud

spring-cloud-starter-netflix-eureka-client

org.springframework.cloud

spring-cloud-starter-bus-amqp

org.springframework.boot

spring-boot-starter-actuator

b. 主启动

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.config.server.EnableConfigServer;

import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication

@EnableConfigServer

@EnableEurekaClient

public class ConfigServerApp {

public static void main(String[] args) {

SpringApplication.run(ConfigServerApp.class, args);

}

}

c. yml配置文件

server:

port: 9527

spring:

application:

name: config-server

# spring cloud config

cloud:

config:

server:

# git 的 远程仓库地址

git:

uri: https://gitee.com/hearts1/config-ydl.git

force-pull: true

username: hearts1

password: Bayueershisi0824

label: master # 分支配置

#配置rabbitmq信息

rabbitmq:

host: 124.221.54.94

port: 5672

username: guest

password: guest

virtual-host: /

eureka:

client:

service-url:

defaultZone: http://localhost:8761/eureka

# 暴露bus的刷新端点

management:

endpoints:

web:

exposure:

include: 'bus-refresh'

d. 在eureka-provider中添加依赖

org.springframework.boot

spring-boot-starter-actuator

org.springframework.cloud

spring-cloud-starter-config

org.springframework.cloud

spring-cloud-starter-bus-amqp

e. bootstrap配置文件

# 配置config-server地址

# 配置获得配置文件的名称等信息

spring:

cloud:

config:

# 配置config-server地址

#uri: http://localhost:9527

# 配置获得配置文件的名称等信息

name: provider # 文件名

profile: dev # profile指定, config-dev.yml

label: master # 分支

discovery:

enabled: true

service-id: CONFIG-SERVER

#配置rabbitmq信息

rabbitmq:

host: 124.221.54.94

port: 5672

username: guest

password: guest

virtual-host: /

management:

endpoints:

web:

exposure:

include: '*'

f. controller上添加注解@RefreshScope // 开启刷新功能

@RestController

@RequestMapping("/goods")

@RefreshScope // 开启刷新功能

public class GoodsController {

...........

}

g. 当eureka-provider中配置文件发生改变时发送请求

curl -X POST http://localhost:9527/actuator/bus-refresh

精彩链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: