• SpringCloud微服务框架搭建


    SpringCloud微服务框架搭建

    以上是我的springcloud项目,eureka是注册中心,ribbon和feign都是cloud的rpc远程调用。

    首先先创建空项目Empty Project

    一、注册中心Eureka

    1.创建基于web的Maven项目(springcloud)
    2.创建服务注册中心。在springcloud项目中创建SpringBoot项目(springboot):

    选中项目右击–>New–>Module

    勾选Cloud Discovery–>Eureka server。以方便导包。

    3.编写springboot项目

    3.1 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.6.4</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.cy</groupId>
        <artifactId>eureka-server</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>eureka-server</name>
        <description>Eureka Server project for Spring Boot</description>
        <properties>
            <java.version>1.8</java.version>
            <spring-cloud.version>2021.0.1</spring-cloud.version>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
        <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>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>

    网上很多用spring cloud starter eureka server 但是官方弃用了,这里使用 spring-cloud-starter-netflix-eureka-server

    3.2修改application.yml文件

    server:
      port: 8761
    eureka:
      instance:
        hostname: localhost
      client:
        registerWithEureka: false
        fetchRegistry: false
        serviceUrl:
          defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka

    registerWithEureka 和 fetchRegistry 设置为false,表明自己属于服务中心主体
    为什么要用yml文件?而不是xml或properties文件?
    说明:xml或properties文件都是以标签来配置数据,这样就造成了资源的浪费,不利于我们开发大型项目,而yml(yaml)文件则取消了这样的配置,文件中都是以数据为中心,层级结构以空格作为层级分隔符。使数据得到突出,简化了开发,同时占用的资源也更少。

    3.3编写启动类SpringbootApplication.java

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

    添加@EnableEurekaServer,该注解表明标注类是一个Eureka Server。

    4.启动项目

    在浏览器中输入http://localhost:8761/

     

    二、 服务提供者

    创建一个服务提供者 (eureka client),当client向server注册时,它会提供一些元数据,例如主机和端口,URL,主页等。Eureka server 从每个client实例接收心跳消息。 如果心跳超时,则通常将该实例从注册server中删除。

    1 创建项目service-support

    略,和上文相似,pom文件和yml配置见下文

    2、配置

    2.1 引入maven依赖

    <?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.6.4</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.cy</groupId>
        <artifactId>service-support</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>service-support</name>
        <description>Service Support project for Spring Boot</description>
        <properties>
            <java.version>1.8</java.version>
            <spring-cloud.version>2021.0.1</spring-cloud.version>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
        <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>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>

    2.2 application.yml配置

    server:
      port: 8762
    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8761/eureka/
    spring:
      application:
        name: service-support

    2.3 加注解@EnableEurekaClient

    表明自己是一个eurekaclient.

    @SpringBootApplication
    @EnableEurekaClient
    public class ServiceSupportApplication {
    
        public static void main(String[] args) {
            try{
                SpringApplication.run(ServiceSupportApplication.class, args);
            }catch (Exception e){
                e.printStackTrace();
            }
    
        }
    
    }
    

    2.4 创建controller

    @RestController
    public class TestController {
    
        @Value("${server.port}")
        String port;
    
        @RequestMapping(value = "/support",method = RequestMethod.GET)
        public String home(@RequestParam String name)
        {
            return "hi " + name + ",i am from port:" + port;
        }
    }

    2.5演示效果

    需要指明spring.application.name,这个很重要,这在以后的服务与服务之间相互调用一般都是根据这个name 。 启动工程,打开http://localhost:8761 ,即eureka server 的网址

    你会发现一个服务已经注册在服务中了,服务名为SERVICE-SUPPORT ,端口为8762(上图是因为我启动了两次,不同端口)
    这时打开 http://localhost:8762/support?name=forezp ,你会在浏览器上看到 :
    hi forezp,i am from port:8762

    三、 服务消费者(Feign)

    什么是Feign Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单。使用Feign,只需要创建一个接口并注解。 它具有可插拔的注解特性,可使用Feign 注解和JAX-RS注解。Feign支持可插拔的编码器和解码器。 Feign默认集成了Ribbon,并和Eureka结合,默认实现了负载均衡的效果。 简而言之: Feign 采用的是基于接口的注解 Feign 整合了ribbon

    1准备工作

    启动eureka-server,端口为8761; 启动service-support 两次,端口分别为8762 、8773.

    2新建一个spring-boot工程,

    取名为serice-feign,代码如下:

    2.1 编辑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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.6.4</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.cy</groupId>
        <artifactId>service-feign</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>service-feign</name>
        <description>Service-feign project for Spring Boot</description>
        <properties>
            <java.version>1.8</java.version>
            <spring-cloud.version>2021.0.1</spring-cloud.version>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
        <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>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>

    2.2 application.yml配置

    在工程的配置文件application.yml文件,指定程序名为service-feign,端口号为8765,服务注册地址为http://localhost:8761/eureka/ ,代码如下:

    server:
      port: 8765
    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8761/eureka/
    spring:
      application:
        name: service-feign

    2.3定义一个feign接口

    /**绑定service-support服务,调用该服务的support方法*/
    @FeignClient(value = "service-support")
    public interface SchedualServiceHi {
        @RequestMapping(value = "/support", method = RequestMethod.GET)
        String sayHiFromClientOne(@RequestParam(value = "name") String name);
    }
    

      

    2.4一个”/hi”的API接口

    @RestController
    public class HiController {
        @Autowired
        SchedualServiceHi schedualServiceHi;
        @RequestMapping(value = "/hi",method = RequestMethod.GET)
        public String sayHi(@RequestParam String name){
            return schedualServiceHi.sayHiFromClientOne(name);
        }
    }

    2.5启动方式

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

    2.6演示效果

    启动程序,多次访问http://localhost:8765/hi?name=forezp(http://localhost:8765/hi?name=forezp),浏览器交替显示:

    hi forezp,i am from port:8762 hi forezp,i am from port:8763

    四、Ribbon

    1、创建springboot项目,命名service-ribbon

    2、编辑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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.6.4</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.cy</groupId>
        <artifactId>service-ribbon</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>service-ribbon</name>
        <description>Service-ribbon project for Spring Boot</description>
        <properties>
            <java.version>1.8</java.version>
            <spring-cloud.version>2021.0.1</spring-cloud.version>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
    <!--        <dependency>-->
    <!--            <groupId>org.springframework.cloud</groupId>-->
    <!--            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>-->
    <!--            <version>2.2.6.RELEASE</version>-->
    <!--        </dependency>-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
                <version>2.1.0.RELEASE</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
        <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>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>

    3、yml文件

    server:
      port: 8764
    spring:
      application:
        name: service-ribbon
    eureka:
      client:
        registerWithEureka: true
        fetchRegistry: true
        serviceUrl:
          defaultZone: http://localhost:8761/eureka/

    4、启动类

    @SpringBootApplication
    @EnableDiscoveryClient
    public class ServiceRibbonApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ServiceRibbonApplication.class, args);
        }
    
        @Bean
        @LoadBalanced
        RestTemplate restTemplate()
        {
            return new RestTemplate();
        }
    
        }

    5、controller和service

    @RestController
    public class HelloControler {
        @Autowired
        HelloService helloService;
        @RequestMapping(value = "/hi",method = RequestMethod.GET)
        public String hi(@RequestParam String name)
        {
            return helloService.hiService(name);
        }
    
    }
    
    
    
    
    @Service
    public class HelloService {
        @Autowired
        RestTemplate restTemplate;
        public String hiService(String name)
        {
            return restTemplate.getForObject("http://service-support/"+"support?name=" + name, String.class);
        }
    
    }

    6、访问

    localhost:8764/hi?name=forezp

     

    踩坑记录:配置负载均衡ribbon,在加入@LoadBalanced启动后就报错No instances available for service-support

    spring-cloud-starter-netflix-eureka-client 3.0版本的已经内置ribbon了,所以我们导入的spring-cloud-starter-netflix-ribbon会与之冲突,这里去掉spring-cloud-starter-netflix-ribbon就解决了

    参考博客:https://www.cnblogs.com/wangpaipilot/articles/14372787.html

    五、Hystrix断路器

    在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以相互调用(RPC),在Spring Cloud可以用RestTemplate+Ribbon和Feign来调用。为了保证其高可用,单个服务通常会集群部署。由于网络原因或者自身的原因,服务并不能保证100%可用,如果单个服务出现问题,调用这个服务就会出现线程阻塞,此时若有大量的请求涌入,Servlet容器的线程资源会被消耗完毕,导致服务瘫痪。服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的“雪崩”效应。
    为了解决这个问题,业界提出了断路器模型。
    7.1 什么是Hystrix
    Netflix开源了Hystrix组件,实现了断路器模式,SpringCloud对这一组件进行了整合。 在微服务架构中,一个请求需要调用多个服务是非常常见的,如下图:


    image.png
     

    较底层的服务如果出现故障,会导致连锁故障。当对特定的服务的调用的不可用达到一个阀值(Hystric 是5秒20次) 断路器将会被打开。


    image.png
     

    断路打开后,可用避免连锁故障,fallback方法可以直接返回一个固定值。

    准备工作

    这篇文章基于上一篇文章的工程,首先启动上一篇文章的工程,启动eureka-server 工程;启动service-hi工程,它的端口为8762。
    在ribbon使用断路器
    改造serice-ribbon 工程的代码,首先在pox.xml文件中加入spring-cloud-starter-hystrix的起步依赖:

    <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
                <version>2.1.0.RELEASE</version>
            </dependency>

    改造service
    改造HelloService类,在hiService方法上加上@HystrixCommand注解。该注解对该方法创建了熔断器的功能,并指定了fallbackMethod熔断方法,熔断方法直接返回了一个字符串,字符串为”hi,”+name+”,sorry,error!”,代码如下:

    
    
    @Service
    public class HelloService {
    @Autowired
    RestTemplate restTemplate;
    //断路器,远程调用失败的回调函数
    @HystrixCommand(fallbackMethod = "hiError")
    public String hiService(String name)
    {
    return restTemplate.getForObject("http://service-support/"+"support?name=" + name, String.class);
    }

    public String hiError(String name) {
    return "hi," + name + ",sorry,error!";
    }

    }
    
    

    在启动类上加入

    @SpringBootApplication
    @EnableDiscoveryClient
    @EnableHystrix   //断路器
    public class ServiceRibbonApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ServiceRibbonApplication.class, args);
        }
    
        @Bean
        @LoadBalanced
        RestTemplate restTemplate()
        {
            return new RestTemplate();
        }
    
        }

    把service-support服务停掉,然后测试

    演示效果

    源码地址:https://github.com/yao5758/spring-cloud-parent-demo.git
  • 相关阅读:
    Java实现 蓝桥杯 算法训练 画图(暴力)
    Java实现 蓝桥杯 算法训练 画图(暴力)
    Java实现 蓝桥杯 算法训练 相邻数对(暴力)
    Java实现 蓝桥杯 算法训练 相邻数对(暴力)
    Java实现 蓝桥杯 算法训练 相邻数对(暴力)
    Java实现 蓝桥杯 算法训练 Cowboys
    Java实现 蓝桥杯 算法训练 Cowboys
    55. Jump Game
    54. Spiral Matrix
    50. Pow(x, n)
  • 原文地址:https://www.cnblogs.com/yao5758/p/16029413.html
Copyright © 2020-2023  润新知