springcloud开发文档

SpringCloud开发

版本控制

<!-- SpringBoot版本管理 -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.5.RELEASE</version>
    <relativePath/>
</parent>
 <!--定义springcloud使用版本号-->
<properties>
    <java.version>1.8</java.version>
    <spring-cloud.version>Hoxton.SR6</spring-cloud.version>
</properties>
<!--全局管理springcloud版本,并不会引入具体依赖-->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

服务注册与发现

Eureka

Eureka-Server
pom.xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- eureka服务端依赖-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
application.properties
# 执行服务端口
server.port=8761
# 指定服务名称 唯一标识
spring.application.name=eurekaServer
# 指定服务注册中心的地址
eureka.client.service-url.defaultZone=http://localhost:8761
# 关闭erueka client立即注册
eureka.client.fetch-registry=false
# 让当前应用仅仅是服务注册中心
eureka.client.register-with-eureka= false
# 关闭自我保护机制
eureka.server.enable-self-preser=false
# 设置刷新时间
eureka.server.eviction-interval-timer-in-ms=3000
开启

EurekaServer服务

@SpringBootApplication
@EnableEurekaServer  // 开启Eureka服务端
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class,args);
    }
}
EureKa-Client
pom.xml
 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- eureka-server依赖-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
application.properties
# 服务端口号
server.port= 8762
# 服务名称
spring.application.name= EurekaClient
# 指定服务注册中心的地址
eureka.client.service-url.defaultZone= http://localhost:8761/eureka
# 用来修改eureka server默认接受心跳的最大时间默认是90s .
eureka.instance.lease-expiration-duration-in-seconds=10
# 指定客户端多久向eureka server发送 - -次心跳默认是30s 
eureka.instance.lease-renewal-interval-in-seconds=5
开启

EurekaClient服务

@SpringBootApplication
@EnableEurekaClient // 开启Eureka客户端
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class,args);
    }
}

Consul(重点)

Consul 的使用
<!-- 切换目录 -->
cd consul
<!-- 启动consul -->
consul agent -dev
consul agent -server
<!-- 访问consul管理界面 -->
http://localhost:8500
<!-- 指定数据中心启动 -->
consul agent -dev --datacenter=aa 
<!-- 推荐配置 -->
path = F:\java\consul

dc1:数据中心

service:当前consul中注册的服务列表

node:用来查看consul中的集群节点

pom.xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- consul依赖 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
 <!-- consul心跳健康检查 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
application.properties
# 指定服务端口号
server.port= 8082
# 指定服务名称
spring.application.name=consulClient
# consul server服务注册地址
spring.cloud.consul.host= localhost
# consul server服务默认端口号
spring.cloud.consul.port= 8500
# 之策当前服务的服务名称 默认:${spring.application.name}
spring.cloud.consul.discovery.service-name=${spring.application.name}
开启

consul 服务

@SpringBootApplication
@EnableDiscoveryClient //开启服务注册
public class ConsulClientApplication {
    public static void main(String[] args) {
   		SpringApplication.run(ConsulClientApplication.class,args);
    }
}

服务间通信(负载均衡)

Rest Template

User 模块(端口号:8764)

@RestController
@RequestMapping("user")
public class UserController {
    private static final Logger log = LoggerFactory.getLogger(UserController.class);
    @GetMapping
    public String getMsg(){
        log.info("user...");
        RestTemplate restTemplate = new RestTemplate();
        String forObject = restTemplate.getForObject("http://localhost:8765/order", String.class);
        return forObject;
    }
}

Order 模块(端口号:8765)

@RestController
@RequestMapping("order")
public class OrdersController {
    private static final Logger log = LoggerFactory.getLogger(OrdersController.class);
    @GetMapping
    public String getMsg(){
        log.info("orders...");
        return "orders...demo 已执行";
    }
}

Ribbon

  • 负载均衡的客户端组件

  • 实现请求调用时的负载均衡

pom.xml
<!--引入ribbon依赖-->
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
application.properties
# 修改用户服务调用订单服务默认负载均衡策略不再使用轮询
orders.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule

Ribbon + Rest Template

**(方案一) **使用DiscoveryClient进行服务调用

@Autowired
private DiscoveryClient discoveryClient; //获取DiscoveryClient服务对象
@GetMapping
public String get(){
    //通过实例名获取服务集群
    List<ServiceInstance> users = discoveryClient.getInstances("orders");
    RestTemplate restTemplate = new RestTemplate();
    users.forEach(user ->{
        log.info("服务名:{},服务路径:{}",user.getServiceId(),user.getUri());
   	 });
	 //获取示例对应url,拼接请求,返回请求结果
    String forObject = restTemplate.getForObject(users.get(0).getUri() + "/order", String.class);
    log.info("DiscoveryClient:{}",forObject);
    return "ok";
}

(方案二) 使用LoadBalanceClient进行服务调用

@Autowired
private LoadBalancerClient loadBalancerClient;  //获取LoadBalancerClient服务对象
@GetMapping
public String get(){
    //获取服务
    ServiceInstance orders = loadBalancerClient.choose("orders"); //默认轮询 
    RestTemplate restTemplate = new RestTemplate();
    log.info("服务地址:{} 服务主机:{} 服务端口:{}",orders.getUri(),orders.getHost(),orders.getPort());
    return restTemplate.getForObject(orders.getUri()+"/order",String.class);
}

**(方案三)**使用LoadBalanced注解进行服务调用

// 使用LoadBalanced注解  作用:可以让对象具有ribbon负载均衡特性
@GetMapping
@LoadBalanced
public String get(){
    return restTemplate.getForObject("http://orders/order",String.class);
}

OpenFeign(重点)

pom.xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- openfeign客户端组件依赖 -->
 <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
application.properties

product服务

server.port=8768
spring.application.name=PRODUCT
spring.cloud.consul.host=localhost
spring.cloud.consul.port=8500

category服务

server.port=8767
spring.application.name=CATEGORY
spring.cloud.consul.host=localhost
spring.cloud.consul.port=8500
# 配置类别调用商品服务openfeign默认超时时间 默认时间1s(指定某个服务超时时间)
feign.client.config.PRODUCT.connectTimeout = 5000
feign,client.config.PRODUCT.readTimeout = 5000
# 修改openfeign默认调用所有服务超时时间
feign.client.config.default.connectTimeout = 5000
feign.client.config.default.readTimeout = 5000
# 开启feign客户端组件打印日志功能
logging,level.com.ls.feignclient = debug
# 开启openfeign中调用商品服务日志展示类型(请求体参数)
feign.client.config.PRODUCT.loggerLevel = full
feign.client.config.ORDER.loggerLevel = none
开启注解
@SpringBootApplication
@EnableDiscoveryClient //开启服务与注册
@EnableFeignClients //起开feign客户端的调用
public class CategoryApplication {
    public static void main(String[] args) {
        SpringApplication.run(CategoryApplication.class,args);
    }
}
配置接口
@FeignClient("PRODUCT")//服务名称
@RequestMapping("product")
public interface ProductClient {
    @GetMapping
    String product();
    //接口传参test?name=xxx&age=23
    @GetMapping("/findOne")
 	 String findOne(@RequestParam("productId") String productId);
    //路径传参/test/{id}/{name}
    @GetMapping("/test/{id}/{name}")
    String test(@PathVariable("id") Integer id,@PathVariable("name") String name);
    //对象传参
    @GetMapping("/test")
    String test(@RequestBody Product product);
    //数组传参
    @GetMapping("/test")
    String test(@requestParam String[] ids);
    //集合传参
    @GetMapping("/test")
    String test(@RequestParam("ids") String[] ids);
    //申明返回对象 
    @GetMapping("/test/{id}")
    Product test(@PathVariable("id") Integer id);
}
Controller

ProductController

@RestController
public class ProductController {
    private static final Logger log = LoggerFactory.getLogger(ProductController.class);
    @Value("${server.port}")
    private int port;
    //Map集合传参
    @GetMapping("/productList")
    public Map<String,Object> findByCategoryIdAndPage(Integer page, Integer rows, Integer categoryId){
        log.info("当前页: {} 每页显示记录数:{} 当前类别id:{} ",page,rows,categoryId);
        //根据类别id分页查询符合当前页集合数据  List<Product>   select * from t_product where categoryId=? limt ?(page-1)*rows,?(rows)
        //根据类别id查询当前类别下总条数       totalCount           select count(id) from t_product where categoryId=?
        Map<String, Object> map = new HashMap<>();
        List<Product> products = new ArrayList<>();
        products.add(new Product(1,"短裙",23.23,new Date()));
        products.add(new Product(2,"超短裙",23.23,new Date()));
        products.add(new Product(3,"超级超短裙",23.23,new Date()));
        int total = 1000;
        map.put("rows",products);
        map.put("total", total);
        return map;
    }
    //list集合对象传参
    @GetMapping("/products")
    public List<Product> findByCategoryId(Integer categoryId){
        log.info("类别id: {}",categoryId);
        //调用业务逻辑根据类别id查询商品列表
        List<Product> products = new ArrayList<>();
        products.add(new Product(1,"短裙",23.23,new Date()));
        products.add(new Product(2,"超短裙",23.23,new Date()));
        products.add(new Product(3,"超级超短裙",23.23,new Date()));
        return products;
    }
    //restful传参
    @GetMapping("/product/{id}")
    public Product product(@PathVariable("id") Integer id){
        log.info("id:{}",id);
        return new Product(id,"超短连衣裙",23.23,new Date());
    }
    //集合传参
    //springmvc 不能直接接受集合类型参数,如果想要接收集合类型参数必须将集合放入对象中,使用对象的方式接收才行
    //oo: oriented(面向) object(对象) 面向对象
    // vo(value object): 用来传递数据对象称之为值对象
    // dto:(data transfer(传输) object):数据传输对象
    @GetMapping("/test4")
    public String test4(CollectionVO collectionVO){
        collectionVO.getIds().forEach(id-> log.info("id:{} ",id));
        return "test4 ok,当前服务端口为: "+port;
    }
    //数组传参
    @GetMapping("/test3")
    public String test3(String[] ids){
        for (String id : ids) {
            log.info("id: {}",id);
        }
        //手动转为list List<String> strings = Arrays.asList(ids);
        return "test3 ok,当前服务端口为: "+port;
    }
    //对象传参
    @PostMapping("/test2")
    public String test2(@RequestBody Product product){
        log.info("product:{}",product);
        return "test2 ok,当前服务端口为: "+port;
    }
    //路径传参
    @GetMapping("/test1/{id}/{name}")
    public String test1(@PathVariable("id") Integer id,@PathVariable("name") String name){
        log.info("id:{}    name:{}",id,name);
        return "test1 ok,当前服务端口为: "+port;
    }
    //零散类型参数接口queryString
    @GetMapping("/test")
    public String test(String name, Integer age){
        log.info("name:{}     age:{}",name,age);
        return "test ok,当前服务端口为: "+port;
    }
    @GetMapping("/product")
    public String product() throws InterruptedException {
        log.info("进入商品服务.....");
        //Thread.sleep(2000);
        return  "product ok,当前提供服务端口:"+port;
    }
    @GetMapping("/list")
    public String list(HttpServletRequest request,String color){
        String header = request.getHeader("User-Name");
        System.out.println("获取对应请求参数 color: "+color);
        System.out.println("获取请求头信息: "+header);
        log.info("商品列表服务");
        return "list ok当前提供服务端口:"+port;
    }
}

CateController

@RestController
@RequestMapping("category")
public class CategoryController {
    private static final Logger log = LoggerFactory.getLogger(CategoryController.class);
    @Autowired
    //获取注入接口对象
    private ProductClient productClient;
    @GetMapping
    public String category(){
        log.info("category server ...");
        //获取请求返回值
        String product = productClient.product();
        log.info("服务请求:{}",product);
        return "category ok..." + product;
    }
}

Hystrix(弹性处理)

熔断

pom.xml
<!-- 已然集成,无需再引入 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
application.properties
#开启openfeign在调用服务过程中,开启hystrix支持, 默认:没有开启
feign.hystrix.enabled=true
开启
@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker //开启hystrix服务的熔断功能
public class HystrixApplication {
    public static void main(String[] args) {
        SpringApplication.run(HystrixApplication.class,args);
    }
}
熔断处理
@RestController
@RequestMapping("hystrix")
public class HystrixController {

    @GetMapping
    @HystrixCommand(fallbackMethod = "demoFallBack")//熔断之后处理FallBackMethod 书写快速失败方法名
    public String demo(Integer id){
        System.out.println("demo ok !!!");
        if (id<=0){
            throw new RuntimeException("无效id!!!!");
        }
        return "demo ok !!!";
    }

    public String demoFallBack(Integer id){
        return "当前活动过于火爆,服务已经被熔断~";
    }
    
     @GetMapping
    @HystrixCommand(defaultfallback = "demoFallBack")//熔断之后处理FallBackMethod 书写快速失败方法名
    public String demo(Integer id){
        System.out.println("demo ok !!!");
        if (id<=0){
            throw new RuntimeException("无效id!!!!");
        }
        return "demo ok !!!";
    }
}
测试
@RestController
public class DemoController {
    //注入openfeign客户端对象
    @Autowired
    private OpenFeignClient openFeignClient;
    @GetMapping("demo")
    public String test(){
        System.out.println("test ok !!!");
        String demoResult = openFeignClient.demo(-1);
        System.out.println("demo result :" + demoResult);
        return "test ok ~~~";
    }
}
OpenFeignClient
//fallback : 这个属性用来指定当前调用服务不可用时,默认的备选处理
@FeignClient(value = "HYSTRIX",fallback = HystrixClientFallBack.class)
public interface OpenFeignClient {
    @GetMapping("demo")
    String demo(@RequestParam("id") Integer id);
}
默认备选处理
# 自定义OpenFeignClient默认备选处理
@Configuration
public class HystrixClientFallBack implements OpenFeignClient {
    @Override
    public String demo(Integer id) {
        return "当前服务不可用,请稍后再试!id:" +id;
    }
}

Hystrix DashBoard

pom.xml
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-consul-discovery</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-dashboard</artifactId>
    </dependency>
</dependencies>
application.properties
server.port=8770
spring.application.name=HYSTRIXDASHBOARD
spring.cloud.consul.host=localhost
spring.cloud.consul.port=8500
开启
# 4.监控的项目中入口类中加入监控路径配置[新版本坑],并启动监控项目
@Bean
public ServletRegistrationBean getServlet() {
    HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
    ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
    registrationBean.setLoadOnStartup(1);
    registrationBean.addUrlMappings("/hystrix.stream");
    registrationBean.setName("HystrixMetricsStreamServlet");
    return registrationBean;
}

gateway(服务网关)

路由转发
pom.xml
<dependency> <!--引入web以来回合gateway发生冲突-->
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
application.yaml
server:
  port: 8771
spring:
  application:
    name: GATAWAY
  cloud:
    consul:
      host: localhost
      port: 8500
    gateway:
      routes:
        - id: cateway_router  #路由对象唯一标识
          # uri: http://localhost:8767/ #用来类别服务地址 http://localhost:8787/category
          uri: lb://CATEGORY # 实现请求的负载均衡 'lb'= 负载均衡
          predicates: #断言 用来配置路由规则
            - Path=/category/** #基于指定的路径方式请求进行路由
            - Method=GET,POST #基于指定的请求方式请求进行路由
            - After=2020-07-21T11:39:33.993+08:00[Asia/Shanghai]
            - Cookie=username,[A-Za-z0-9]+
            - Header=X-Request-Id, \d+
         filters:
            - AddRequestParameter=id,34
            - AddResponseHeader=username,chenyn
            
        - id: product_router
          # uri: http://localhost:8768/ #用来类别服务地址 http://localhost:8788/list
          uri: lb://PRODUCT # 实现请求的负载均衡
          predicates: #断言 用来配置路由规则
            - Path=/product/**,/list/**
management:
  endpoints:
    web:
      exposure:
        include: "*"   #开启所有web端点暴露
- 访问路由管理列表地址
- http://localhost:8989/actuator/gateway/routes
java配置的方式
@Configuration
public class GatewayConfig {
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
            .route("category_router", r -> r.path("/category/**")
                   .uri("http://localhost:8767/"))
            .route("product_router",r -> r.path("/product/**")
                   .uri("http://localhott:8768"))
            .build();
    }
}

Config(配置注册中心)

config-server

pom.xml
<dependency> <!--引入web以来回合gateway发生冲突-->
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
</dependency>
application.yaml
server:
  port: 8772

spring:
  application:
    name: CONFIGSERVER
  cloud:
    consul:
      port: 8500
      host: localhost
    config:
      server:
        git: 
          uri:  https://gitee.com/xiaoye_ls/config.git #远端仓库地址
        default-label: master
开启
@SpringBootApplication
@EnableConfigServer //开启统一配置中心服务
public class ConfigServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConfigServerApplication.class,args);
    }
}

config-client

pom.xml
<dependencies>
    <!--web-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--consul-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-consul-discovery</artifactId>
    </dependency>
    <!--actuator-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
	 <!--config-client-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>
</dependencies>
远端仓库配置
configclient.properties
server.port: 8990
spring.application.name: CONFIGCLIENT
spring.cloud.consul.host: localhost
spring.cloud.consul.port: 8500
spring.profiles.active: dev
configclient-dev.properties
name: zhangsan
configclient-prod.properties
name: xiaosan
远端仓库截图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lZtuKNhE-1631424677869)(springcloud开发.assets/image-20210724125938352.png)]

bootstrap.properties
# 告诉当前configclient统一配置中心在注册中心服务id
spring.cloud.config.discovery.service-id = CONFIGSERVER
# 开启当前configclient 根据服务id去注册中心获取
spring.cloud.config.discovery.enabled = true

# 配置注册中心
spring.cloud.consul.host= localhost
spring.cloud.consul.port= 8500

# 获取那个配置文件 1、确定分支  2、确定文件名  3、确定环境
spring.cloud.config.label = master
spring.cloud.config.name = configclient
spring.cloud.config.profile = prod
ConfigController
@RestController
public class ConfigController {
    @Value("${name}")
    private String name;
    @GetMapping("name")
    public String getName(){
        return name;
    }
}
手动刷新远端仓库修改后问配置文件
configController
@RestController
@RefreshScope  //刷新域注解  作用:远端仓库被刷新后,自动同步数据
public class ConfigController {

    @Value("${name}")
    private String name;

    @GetMapping("name")
    public String getName(){
        return name;
    }
}
application.properties
#开启所有web端点暴露  [推荐使用这种]
management.endpoints.web.exposure.include=*
发送刷新请求
# 手动调用刷新配置接口
- curl -X POST http://localhost:9099/actuator/refresh

Bus(远端git仓库同步刷新)

pom.xml

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>

application.properties

# 统一配置
#连接主机
spring.rabbitmq.host=localhost						
#连接mq端口
spring.rabbitmq.port=5672							
#连接mq用户名
spring.rabbitmq.username=user						
#连接mq密码
spring.rabbitmq.password=password					
# 客户端配置
#防止第一次链接不到远程,信息无法获取而导致服务器报错
spring.cloud.config.fail-fast=true
#开启所有web端点暴露  [推荐使用这种]
management.endpoints.web.exposure.include=*

刷新

# 默认情况下使用,类似广播的方式刷新全部配置
	curl -X POST http://localhost:7878/actuator/bus-refresh 
# 指定端口刷新某个具体服务: 
	curl -X POST http://localhost:7878/actuator/bus-refresh/configclient:9090
# 指定服务id刷新服务集群节点: 
	curl -X POST http://localhost:7878/actuator/bus-refresh/configclient
 	[注意:][configclient代表刷新服务的唯一标识]

springcloud-alibaba

nacos

服务的注册

pom.xml
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--引入nacos client的依赖-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
</dependencies>
application.properties
# 端口号
server.port= 8501
# 服务名
spring.application.name= NACOSCLIENT
# nacos客户端配置
spring.cloud.nacos.server-addr= 192.168.1.3:8848
# 作为nacos client注册地址
spring.cloud.nacos.discovery.server-addr=${spring.cloud.nacos.server-addr}
# 指定向nacos server 注册服务名称
spring.cloud.nacos.discovery.service= ${spring.application.name}
SpringBootApplication
@SpringBootApplication
//@EnableDiscoveryClient
public class NacosClientApplication {
    public static void main(String[] args) {
        SpringApplication.run(NacosClientApplication.class,args);
    }
}

远端配置

pom.xml
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--引入nacos client的依赖-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <!--引入nacos config 依赖-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>
</dependencies>
boostrap.properties
#Nacos远端地址
spring.cloud.nacos.server-addr=10.235.40.42:8848
#配置组
spring.cloud.nacos.config.group=DEFAULT_GROUP
#配置文件名
#spring.application.name=configclient-prod
spring.cloud.nacos.config.name=configclient
#配置文件后缀
spring.cloud.nacos.config.file-extension=properties
#配置环境
spring.profiles.active=prod
SpringBootApplication
@SpringBootApplication
@RefreshScope
public class ConfigClientApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConfigClientApplication.class,args);
    }
}
controller
@Value("${user.name}")
private String username;

@GetMapping("get")
public String getMsg(){
    return "远端仓库配置user.name"+ username;
}
远端配置
server.port=8504
spring.application.name=CONFIGCLIENT
spring.cloud.nacos.discovery.server-addr=${spring.cloud.nacos.server-addr}
user.name='liushun'

sentinel

启动sentinel

# linux启动jar
java -jar -Dserver.port=9191 sentinel-dashboard-1.7.2.jar

pom.xml

<dependencies>
    <!--web-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--nacos client-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <!--sentinel-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>
</dependencies>

application.properties

server.port= 8505
spring.cloud.nacos.server-addr=192.168.1.6:8848
spring.application.name=SENTINEL
# 开启sentinel保护
feign.sentinel.enabled=true
# 配置sentinel传输端口
spring.cloud.sentinel.transport.dashboard=192.168.1.6:9191
# 指定sentinel组件与sentinel DashBoard 通信端口
spring.cloud.sentinel.transport.port=8719

controller

@RestController
public class DemoController {
    private static final Logger logger = LoggerFactory.getLogger(DemoController.class);
    @GetMapping("demo")
    public String demo(){
        logger.info("demo ok!!!");
        return "demo ok!!!";
    }
}

springcloud小案例

项目结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uci6gvMu-1631424677873)(springcloud开发.assets/image-20210816175513062-1629107715061.png)]

项目依赖

父项目

<?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>org.example</groupId>
    <artifactId>springcloud-parent</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>springcloud-commons</module>
        <module>springcloud-users</module>
        <module>springcloud-products</module>
        <module>springcloud-gateway</module>
    </modules>

    <properties>
        <spring.cloud.version>Hoxton.SR6</spring.cloud.version>
        <spring.cloud.alibaba.version>2.2.1.RELEASE</spring.cloud.alibaba.version>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-parent</artifactId>
        <version>2.2.5.RELEASE</version>
    </parent>

    <dependencyManagement>
        <dependencies>
            <!--SpringCloud-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring.cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--alibaba-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring.cloud.alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

用户模块

<dependencies>
    <!--web-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--nacos-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    <!--sentinel-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>
    <!--config配置-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>
</dependencies>

商品模块

<dependencies>
    <!--web-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--nacos-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
</dependencies>

网关模块

<dependencies>
    <!--nacos-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <!--gateway-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <!--config-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>
</dependencies>

项目功能

用户模块

RestTemplate+Ribbon
@Configuration
public class BeansConfig {
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}
OpenFeign + Ribbon
@FeignClient("PRODUCTS")
public interface ProductsClient {
    @GetMapping("product")
    String product();
}
功能实现
# 获取商品
@RestController
public class UserController {
    private static final Logger logger = LoggerFactory.getLogger(UserController.class);
    @Value("${server.port}")
    private Integer port;
    //@Autowired
    //private RestTemplate restTemplate;
    @Autowired
    private ProductsClient productsClient;
    @GetMapping("invoke")
    @SentinelResource("INVOKE")
    public String invokeProduct(){
        logger.info("invoke product ok !!!");
        //String result = restTemplate.getForObject("http://PRODUCTS/product", String.class);
        String result = productsClient.product();
        logger.info("result:{}",result);
        return result;
    }
}
主启动类配置
@SpringBootApplication
@EnableFeignClients
@RefreshScope
public class UsersApplication {
    public static void main(String[] args) {
        SpringApplication.run(UsersApplication.class,args);
    }
}
服务集中配置
本地配置
# bootstrap.properties
#Nacos远端地址
spring.cloud.nacos.server-addr=192.168.1.15:8848
#nacos namespace
spring.cloud.nacos.config.namespace=b6c8e7dd-0672-4b2b-8ac7-e71fb7259148
#配置组
spring.cloud.nacos.config.group=USERS
#配置文件名
spring.cloud.nacos.config.name=user
#配置文件后缀
spring.cloud.nacos.config.file-extension=properties
#配置环境
spring.profiles.active=prod
远端配置
# user-prod.properties
# 端口号
server.port= 8888
# 服务名
spring.application.name= USERS
# nacos服务注册中心
spring.cloud.nacos.server-addr= 192.168.1.15:8848
spring.cloud.sentinel.enabled= true
spring.cloud.sentinel.eager= true
spring.cloud.sentinel.transport.port= 8719
spring.cloud.sentinel.transport.dashboard= 192.168.1.15:9191

产品模块

功能实现
@RestController
public class ProductController {
    private static final Logger logger = LoggerFactory.getLogger(ProductController.class);
    @Value("${server.port}")
    private Integer port;
    @GetMapping("product")
    public String product(){
        logger.info("product ok !!!");
        return "product ,端口号:" + port;
    }
}
主启动类配置
@SpringBootApplication
public class ProductApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProductApplication.class,args);
    }
}
基础配置
# application.properties
# 端口号
server.port= 9999
# 服务名
spring.application.name= PRODUCTS
# nacos服务注册中心
spring.cloud.nacos.server-addr= 192.168.1.15:8848

网关模块

主启动类
@SpringBootApplication
@RefreshScope
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class,args);
    }
}
服务集中配置
本地配置
# bootstrap.properties
# 远端配置中心
spring.cloud.nacos.server-addr=192.168.1.15:8848
# 配置nacos命名空间
spring.cloud.nacos.config.namespace=b6c8e7dd-0672-4b2b-8ac7-e71fb7259148
# nacos组
spring.cloud.nacos.config.group=GATEWAYS
# 配置文件名
spring.cloud.nacos.config.name=gateways
# 选择生产环境
spring.profiles.active=prod
# 文件后缀名
spring.cloud.nacos.config.file-extension=yaml
服务端配置
# gateways-prod.yaml
server:
  port: 8990
spring:
  application:
    name: GATEWAY
  cloud:
    nacos:
      server-addr: 192.168.1.15:8848
    gateway:
      routes:
        - id: users_route
          uri: lb://USERSS
          predicates:
            - Path=/invoke
        - id: product_route
          uri: lb://PRODUCTS
          predicates:
            - Path=/product

类配置

@SpringBootApplication
public class ProductApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProductApplication.class,args);
    }
}
基础配置
# application.properties
# 端口号
server.port= 9999
# 服务名
spring.application.name= PRODUCTS
# nacos服务注册中心
spring.cloud.nacos.server-addr= 192.168.1.15:8848

网关模块

主启动类
@SpringBootApplication
@RefreshScope
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class,args);
    }
}
服务集中配置
本地配置
# bootstrap.properties
# 远端配置中心
spring.cloud.nacos.server-addr=192.168.1.15:8848
# 配置nacos命名空间
spring.cloud.nacos.config.namespace=b6c8e7dd-0672-4b2b-8ac7-e71fb7259148
# nacos组
spring.cloud.nacos.config.group=GATEWAYS
# 配置文件名
spring.cloud.nacos.config.name=gateways
# 选择生产环境
spring.profiles.active=prod
# 文件后缀名
spring.cloud.nacos.config.file-extension=yaml
服务端配置
# gateways-prod.yaml
server:
  port: 8990
spring:
  application:
    name: GATEWAY
  cloud:
    nacos:
      server-addr: 192.168.1.15:8848
    gateway:
      routes:
        - id: users_route
          uri: lb://USERSS
          predicates:
            - Path=/invoke
        - id: product_route
          uri: lb://PRODUCTS
          predicates:
            - Path=/product
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值