springcloud初探-搭建微服务、Eureka实现服务提供者集群、Feign简化消费者操作+负载均衡和熔断器等

springcloud

搭建前准备

  • springboot默认的mysql版本是8.几,建立springcloud项目时父工程导入
    以下依赖会出现时区问题:
<!--使用druid整合mysql数据库 -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <scope>runtime</scope>
    </dependency>
  • 创建消费者模块的时候出现了bug,原因是子工程继承父工程的依赖
 <!--使用druid整合mysql数据库 -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <scope>runtime</scope>
    </dependency>

    <!--阿里数据源 -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.1.12</version>
    </dependency>

这些依赖会去寻找数据源,但消费者不需要配置数据源,所以找不到。

Action:

Consider the following:
	If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
	If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active).

解决:
主启动类

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)

搭建微服务工程

在这里插入图片描述

1.建立父工程(打pom包)

pom.xml管理整个微服务工程的依赖
在这里插入图片描述

2.导包

注释掉有关redis的依赖,不然后面的操作可能会出错。

<!--导入springBoot依赖包 -->
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.1.RELEASE</version>
		<relativePath />
	</parent>
	<properties>
		<java.version>1.8</java.version>
	</properties>
	<!--依赖管理,用于管理spring-cloud的依赖 -->
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>Finchley.SR2</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>
	<repositories>
		<repository>
			<id>spring-milestones</id>
			<name>Spring Milestones</name>
			<url>https://repo.spring.io/milestone</url>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</repository>
	</repositories>

	<dependencies>
		<!--导入springCloudjar包 -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-stream</artifactId>
		</dependency>

		<!--引入springBoot jar包 -->
		<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>
		
		<!-- <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency> -->

		<!--支持热部署 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>springloaded</artifactId>
			<version>1.2.8.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
		</dependency>

		<!--整合redis -->
		<dependency>
			<groupId>redis.clients</groupId>
			<artifactId>jedis</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-redis</artifactId>
		</dependency>

		<!--导入pojo插件 -->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
		</dependency>
		
		<!--使用druid整合mysql数据库 -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>

		<!--阿里数据源 -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid</artifactId>
			<version>1.1.12</version>
		</dependency>

		<!--mybatis-plus配置 -->
		<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatis-plus-boot-starter</artifactId>
			<version>3.0.6</version>
		</dependency>
	</dependencies>

2.普通maven创建子工程服务提供者和服务消费者

在这里插入图片描述

3.配置服务提供者和消费者的.yml文件

3.1.服务提供者:

server:
  port: 8082
  servlet:
    context-path: /
#配置访问端口和访问的根路径
#配置数据源
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource #使用druid连接池
    url: jdbc:mysql://localhost:3306/db_shop?characterEncoding=utf8
    password: root
    username: root
    driver-class-name: com.mysql.jdbc.Driver
    druid: #配置 Druid 的相关参数
      # 初始化大小,最小,最大
      initial-size: 5
      min-idle: 5
      max-active: 20
      max-wait: 60000 # 配置获取连接等待超时的时间
      time-between-eviction-runs-millis: 60000  # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位毫秒
      min-evictable-idle-time-millis: 300000   # 配置一个连接在池中最小生存时间
      validation-query: SELECT 1              #SELECT 1 FROM sys_user
      test-while-idle: true
      test-on-borrow: false
      test-on-return: false
      pool-prepared-statements: true  # 打开 PSCache,并且指定每个连接上 PSCache 的大小
      max-pool-prepared-statement-per-connection-size: 20
      #filters: stat,wall,log4j  # 配置监控统计拦截的 Filter,去掉后监控界面 SQL 无法统计,wall 用于防火墙
      web-stat-filter: # 配置 DruidStatFilter
        enabled: true
        url-pattern: /*
        exclusions: .js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*
      stat-view-servlet: # 配置 DruidStatViewServlet
        url-pattern: /druid/*
        # IP 白名单,没有配置或者为空,则允许所有访问
        allow: 127.0.0.1
        # IP 黑名单,若白名单也存在,则优先使用
        deny: 192.168.31.253
        # 禁用 HTML 中 Reset All 按钮
        reset-enable: false
        # 登录用户名/密码
        login-username: root
        login-password: 123456

  #视图解析配置——可配可不配
  mvc:
    view:
      prefix: /templates/
      suffix: .html

#Mybatis——plus
mybatis-plus:
  type-aliases-package: edu.xlh.pojo #配置别名
  mapper-locations: classpath:mappers/*.xml #指定映射文件的位置
  configuration:
    map-underscore-to-camel-case: false  #自动开启驼峰规则映射




3.2.服务消费者:

server:
  port: 8081
  servlet:
    context-path: /

4.服务提供者添加mysql驱动依赖

<dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.45</version>
        </dependency>

5.服务提供者程序入口类

添加@SpringBootApplication注解和@MapperScan("edu.xlh.mapper")扫描持久层包

//主启动类
@SpringBootApplication
@MapperScan("edu.xlh.mapper")
public class SpringCloud8082provider {
    public static void main(String[] args) {
        SpringApplication.run(SpringCloud8082provider.class,args);
    }
}

6.服务消费者程序入口类

添加@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)注解

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class SpringCloud8081consumer {
    public static void main(String[] args) {
        SpringApplication.run(SpringCloud8081consumer.class,args);
    }
}

7.测试

7.1.配置远程调用组件:

在这里插入图片描述

@Configuration
public class RestTemplateConfig {
    @Bean//创建对象交给spring管理
    public RestTemplate getTemplate(){
        return new RestTemplate();
    }
}

7.2.服务提供者-8082:

@Controller
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/provider/getAll")
    @ResponseBody
    public List<User> findAllUserInfo(){
        System.out.println("----------8082服务");
        return userService.findAllUsers();
    }

7.3.服务消费者-8081:

@Controller
@RequestMapping("/user")
public class UserControllerConsumer {
    //PROVIDER-USER代表两个服务提供者的实例
    private String commonUrl="http://localhost:8082/user/";

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping("/consumer/find")
    @ResponseBody
    public List<User> findAllUsers(){
        String url = commonUrl+"provider/getAll";
        List list = restTemplate.getForObject(url, List.class);
        return list;
    }

localhost:8081/user//consumer/find访问

8.抽取接口

8.1.建子模块

在这里插入图片描述

8.2.打jar包安装到本地仓库

在这里插入图片描述

8.3.服务提供者和消费者导入依赖

 <!--引入接口-->
        <dependency>
            <groupId>edu.xlh</groupId>
            <artifactId>springcloud-interface</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

9.通过注册Eureka实现服务提供者集群

9.1.建子模块

在这里插入图片描述

9.2.导入依赖

        <!--添加 eureka 注册中心 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

出错时可能还要加的依赖:

<dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1.1</version>
        </dependency>

9.3.配置application.yml

server:
  port: 7000        #定义注册中心端口
eureka:
  server:
    enable-self-preservation: true  #设定自我保护模式 默认值为true 不建议关闭
  instance:
    hostname: localhost        #eureka服务的实例名称,如果有多个服务名称必须不同
  client:
    register-with-eureka: false   #表示注册中心 不会注册自己本身
    fetch-registry: false         #表示自己就是注册中心,不需要检索服务
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
      #defaultZone: http://localhost:7000/eureka

9.4.建立一个端口为8083的服务提供者

在这里插入图片描述
修改从8082服务提供者copy过来的application.yml中的端口为8083:

server:
  port: 8083
  servlet:
    context-path: /

9.5.在两个服务的提供者和一个消费者application.yml配置Eureka客户端

9.5.1.提供者:

其中instance-id: provider-user-8082与不同端口号服务以此区别,例如8083服务提供者instance-id: provider-user-8083

 #这个是配置Eureka 的客户端
  application: #定义服务名称,如果是多个相同的服务,则名称必须相同
    name: provider-user
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7000/eureka
    instance:
      instance-id: provider-user-8082                 #定义微服务的名称
      prefer-ip-address: true                        #是否显示IP和端口

配置后的yml

server:
  port: 8082
  servlet:
    context-path: /
#配置数据源
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource #使用druid连接池
    url: jdbc:mysql://localhost:3306/db_shop?characterEncoding=utf8
    password: root
    username: root
    driver-class-name: com.mysql.jdbc.Driver
    #这个是配置Eureka 的客户端
  application: #定义服务名称,如果是多个相同的服务,则名称必须相同
    name: provider-user
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7000/eureka
    instance:
      instance-id: provider-user-8082                 #定义微服务的名称
      prefer-ip-address: true                        #是否显示IP和端口


    druid: #配置 Druid 的相关参数
      # 初始化大小,最小,最大
      initial-size: 5
      min-idle: 5
      max-active: 20
      max-wait: 60000 # 配置获取连接等待超时的时间
      time-between-eviction-runs-millis: 60000  # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位毫秒
      min-evictable-idle-time-millis: 300000   # 配置一个连接在池中最小生存时间
      validation-query: SELECT 1              #SELECT 1 FROM sys_user
      test-while-idle: true
      test-on-borrow: false
      test-on-return: false
      pool-prepared-statements: true  # 打开 PSCache,并且指定每个连接上 PSCache 的大小
      max-pool-prepared-statement-per-connection-size: 20
      #filters: stat,wall,log4j  # 配置监控统计拦截的 Filter,去掉后监控界面 SQL 无法统计,wall 用于防火墙
      web-stat-filter: # 配置 DruidStatFilter
        enabled: true
        url-pattern: /*
        exclusions: .js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*
      stat-view-servlet: # 配置 DruidStatViewServlet
        url-pattern: /druid/*
        # IP 白名单,没有配置或者为空,则允许所有访问
        allow: 127.0.0.1
        # IP 黑名单,若白名单也存在,则优先使用
        deny: 192.168.31.253
        # 禁用 HTML 中 Reset All 按钮
        reset-enable: false
        # 登录用户名/密码
        login-username: root
        login-password: 123456
  #视图解析配置
  mvc:
    view:
      prefix: /templates/
      suffix: .html
#mybatis-plus 配置
mybatis-plus:
  type-aliases-package: com.ldk.pojo  #配置实体别名
  mapper-locations: classpath:mappers/*.xml  #指定sql 映射文件的位置
  configuration:
    map-underscore-to-camel-case: false  #自动开启驼峰规则映射

9.5.2.消费者:

server:
  port: 8081
  servlet:
    context-path: /
eureka:
  client:
    register-with-eureka: false    #不会将自己的信息注册到eureka中
    service-url:
      #链接注册中心集群
      defaultZone: http://localhost:7000/eureka

9.6.在两个服务提供者和服务消费者的pom.xml中加入Eureka客户端地址依赖:

 <!--添加eureka 客户端地址 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

9.7.在两个服务提供者和服务消费者的主启动类加上

@EnableEurekaClient

9.8.启动Eureka,访问localhost:7000(可配置其他端口),再启动两个服务提供者

在这里插入图片描述
将服务提供者的controller的private String commonUrl="http://localhost:8082/user/";改为

    //PROVIDER-USER代表两个服务提供者的实例
    private String commonUrl="http://PROVIDER-USER/user/";

9.9.在远程服务调用组件上加入负载均衡策略@LoadBalanced

@Configuration
public class RestTemplateConfig {
    @Bean//创建对象交给spring管理
    //开启负载均衡策略 默认是轮询策略
    @LoadBalanced
    public RestTemplate getTemplate(){
        return new RestTemplate();
    }
}

10.使用Feign简化消费者操作,实现在Eureka中的service调用服务提供者的controller,服务消费者调用Eureka中的service。

注:将消费者controller内的代码先全部注释掉
在这里插入图片描述

10.1.上图模块的pom.xml文件引入

<!--引入Feign支持 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

10.2.编写UserService接口

加上@FeignClient(value = “provider-user”)
@RequestMapping("/user/provider/getAll")为服务提供者某方法的映射。

@FeignClient(value = "provider-user")//指定服务的名称,一定使用小写
public interface UserService {
    @RequestMapping("/user/provider/getAll")
    List<User> findAll();
}

在这里插入图片描述

10.3.服务消费者注入接口的UserService并调用接口方法

 @Autowired
    private UserService userService;

    @GetMapping("/provider/getAll")
    @ResponseBody
    public List<User> findAllUserInfo(){
        System.out.println("----------8082服务");
        return userService.findAllUsers();
    }

10.4.服务消费者的主启动类添加@EnableFeignClients

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableEurekaClient
@EnableFeignClients//开启Feign客户端服务
public class SpringCloud8081consumer {
    public static void main(String[] args) {
        SpringApplication.run(SpringCloud8081consumer.class,args);
    }
}

11.服务的扇出=》Hystrix

定义:一个服务调用多级服务的现象。会导致调用者一直处于等待状态,用户体验不好,资源耗费严重。=>熔断机制。实现:熔断器Hystrix:能够保证当服务单元发生故障后,通过断路器机制.返回一个满足预期处理条件的数据.而不是长时间的等待或者抛出异常.这样就能避免服务长时间没有响应或者报错等影响,提升了软件的可靠性

11.1.两个服务提供者引入依赖

<!--添加断路器配置 -->
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

11.2.在8082提供者controller自定义一个因异常反馈给客户端的方法

注意方法的返回值与抛出异常方法的返回值保持一致。

 //但执行请求的时候,出现故障或者访问延迟的时候
    //就会来调用这个方法作为预期的数据返回给客户端
    public List<User> hystrix_exception(){
        List<User> list = new ArrayList<>();
        User user = new User();
        user.setBemail("服务不可用");
        list.add(user);
        return list;
    }

11.3.在8082提供者controller抛出异常的方法上加 @HystrixCommand(fallbackMethod="hystrix_exception")注解

fallbackMethod值为回调方法的方法名

@GetMapping("/provider/getAll")
    @ResponseBody
    @HystrixCommand(fallbackMethod="hystrix_exception")
    public List<User> findAllUserInfo(){
        int a = 10/0;
        System.out.println("----------8082服务");
        return userService.findAllUsers();
    }

11.4.在8082提供者主启动类加@EnableHystrix

//主启动类
@SpringBootApplication
@MapperScan("edu.xlh.mapper")
@EnableEurekaClient
@EnableHystrix
public class SpringCloud8082provider {
    public static void main(String[] args) {
        SpringApplication.run(SpringCloud8082provider.class,args);
    }
}

11.5.在注册中心的接口中UserService添加熔断器解决8082提供者宕机代码不跑

一般的将断路器配置到服务端,可以返回有效的数据.但是如果服务端程序宕机了.这时断路器机制将不能生效.为了让用户也能快速获取预期数据.所以将断路器配置到接口中。
11.5.1.配置依赖
在这里插入图片描述
pom.xml:

 <!--添加断路器配置 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

11.5.2.建一个回调工厂类
在这里插入图片描述
匿名内部类中方法就是接口的方法

//用户接口回调工厂
@Component
public class UserFallBackFactory implements FallbackFactory<UserService> {
    @Override
    public UserService create(Throwable throwable) {
        return new UserService() {
            @Override
            public List<User> findAll() {
                List<User> list = new ArrayList<>();
                User user = new User();
                user.setBemail("服务不可用");
                list.add(user);
                return list;
            }

            @Override
            public ResponseResult save(User user) {
                return new ResponseResult(201,"服务器已经崩溃");
            }
        };
    }
}

11.5.3.在UserService中补上fallbackFactory= UserFallBackFactory.class

@FeignClient(value = "provider-user",fallbackFactory= UserFallBackFactory.class)//指定服务的名称,一定使用小写
public interface UserService {
    @RequestMapping("/user/provider/getAll")
    List<User> findAll();

    @RequestMapping("/user/provider/save")
    ResponseResult save(User user);
}

11.5.4.消费者的.yml配置文件

feign:
  hystrix:
    enabled: true                 #启动熔断器机制 !!!!!!!!!!!!!

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 3000  #设定断路器超时时间

配置后:

server:
  port: 8081
  servlet:
    context-path: /
eureka:
  client:
    register-with-eureka: false    #不会将自己的信息注册到eureka中
    service-url:
      #链接注册中心集群
      defaultZone: http://localhost:7000/eureka

feign:
  hystrix:
    enabled: true                 #启动熔断器机制 !!!!!!!!!!!!!

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 3000  #设定断路器超时时间


down掉8082再测试,http://localhost:8081/user/consumer/add/123/456/789

12.DashBoard仪表盘监控

监控某个时间的并发量、成功访问数量、失败访问数量、监控系统性能。目的:通过系统的监测:可以有效调用、分配服务器资源,有效解决高并发和资源合理利用。

12.1.建子模块

在这里插入图片描述

12.2.引入依赖

<dependencies>
	<!--添加断路器配置 -->
	<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
	</dependency>

	<!--配置hystrix监控 -->
	<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
	</dependency>
</dependencies>

12.3.子模块.yml配置文件

server:
  port: 9000        #定义注册中心端口

12.4子模块主启动类添加@EnableHystrixDashboard注解

//主启动类
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableHystrixDashboard
public class SpringCloud9000DashBoard {
    public static void main(String[] args) {
        SpringApplication.run(SpringCloud9000DashBoard.class,args);
    }
}

12.5.访问

http://localhost:9000/hystrix

12.6. 8082提供者引入客户端依赖

<!--添加监控  -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

12.7. 8082提供者配置类

在这里插入图片描述

@Configuration
public class DashboardConfig {
    @Bean
    public ServletRegistrationBean<Servlet> getServlet(){
        HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
        ServletRegistrationBean<Servlet> registrationBean = new ServletRegistrationBean<>(streamServlet);
        registrationBean.setLoadOnStartup(1);
        registrationBean.addUrlMappings("/actuator/hystrix.stream");
        registrationBean.setName("HystrixMetricsStreamServlet");
        return registrationBean;
    }

}

12.8.访问

在这里插入图片描述

http://localhost:8082/actuator/hystrix.stream填在上图第一个框,只需修改为提供者端口号,我的为8082。
13.Eureka集群
只需复制模块,比如一共三个,只需修改.yml文件中自己的端口号,和向另外两个注册
7000:

 defaultZone: http://eureka7000.com:7001/eureka,http://eureka7002.com:7002/eureka

7001:

 defaultZone: http://eureka7000.com:7000/eureka,http://eureka7002.com:7002/eureka

7002:

 defaultZone: http://eureka7000.com:7000/eureka,http://eureka7002.com:7001/eureka
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fire king

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值