欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

微服务框架入门(一)

程序员文章站 2022-06-12 22:54:21
...

搭建简单Cloud架构(One)

一、父项目搭建

新建maven项目pom文件修改

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.mmh</groupId>
    <artifactId>mmh-parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <!-- 根据自己需求添加jar -->
    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.14</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.33</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.11</version>
        </dependency>
    </dependencies>
    <modules>
        <module>mmh-models</module>
        <module>mmh-eureka</module>
    </modules>
</project>

删除不必要的子文件夹,如src、mvn之类的留下pom和iml就OK

在父项目基础上创建子项目。

二、Eureka的搭建

微服务框架入门(一)

创建检查pom是否引入eureka坐标

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-netflix-eureka-server</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter</artifactId>
</dependency>

注意<parent>标签填写父项目的信息

<parent>
    <artifactId>mmh-parent</artifactId>
    <groupId>com.mmh</groupId>
    <version>2.0-SNAPSHOT</version>
</parent>

父项目<modules>标签加入此项目

好了不墨迹了,0.0重点来啦:启动类加上@EnableEurekaServer

application.yml 配置文件配置eureka的服务端。

spring:
    application:
        name: xxx

server:
    port: 8761 #启动端口

eureka:
    client:
        registerWithEureka: false  #false:不作为一个客户端注册到注册中心
        fetchRegistry: false      #为true时,可以启动,但报异常:Cannot execute request on any known server

启动访问localhost:8761

微服务框架入门(一)

看到如下界面则成功搭建Eureka的服务端

 附Eureka客户端使用方法:

 引入客户端坐标:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

启动类加入Client的坐标:

@EnableEurekaClient

配置文件application.yml:

eureka:
  client:
    service-url:
        defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true
    ip-address: 127.0.0.1
    instance-id: ${spring.application.name}:${eureka.instance.ip-address}:${server.port} # 状态显示格式

配置即可发现服务:

 

微服务框架入门(一)

Eureka密码配置

依赖坐标:

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

配置文件:

服务端

# 安全认证的配置
security:
  basic:
    enabled: true
  user:
    name: admin  # 用户名
    password: 123456   # 用户密码

客户端

eureka:
  client:
    service-url:
        defaultZone: http://admin:aaa@qq.com:8761/eureka/

 其他配置:

eureka:
    client:
        fetch-registry: true # 是否需要去检索寻找服务,默认是true
        registry-fetch-interval-seconds: 5 # 表示eureka client间隔多久去拉取服务注册信息,默认为30秒,对于gateway,如果要迅速获取服务注册状态,可以缩小该值,比如5秒
    instance:
        health-check-url-path: /xxx/health # 修改实例的状态页面地址,相对路径,也支持绝对路径,例如需要支持https,默认为/info
        lease-expiration-duration-in-seconds: 90 # 表示eureka server至上一次收到client的心跳之后,等待下一次心跳的超时时间;超时移除该instance
        lease-renewal-interval-in-seconds: 5 # 表示eureka client发送心跳给server端的频率,默认5秒

        status-page-url-path: /yyy/info # 修改健康监控地址,相对路径,也支持绝对路径,例如需要支持https,默认为/health

三、服务注册与发现j集成Ribbon负载

Ribbon坐标依赖:

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>

启动类:

package com.yst.test;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableEurekaClient
public class YstTestApplication {
    @Bean
    @LoadBalanced // 这里是重点 加上它才能使用ribbon负载
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(YstTestApplication.class, args);
    }
}

一个测试接口:

package com.yst.test.rest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

/**
 * @program: yst-parent
 * @description: mmh
 * @author: Mr.Miao
 * @create: 2018-08-28 11:28
 **/
@RestController
@RequestMapping("/test")
public class TestController {
    @Autowired
    private RestTemplate restTemplate;
    @GetMapping("/getName")
    public String getName(){
        /*
         * 使用restTemplate调用,YST-RIBBON-ONE 为服务名 即spring.application.name
         * 启动两个 YST-RIBBON-ONE 则会进行负载调用
         */
        return restTemplate.getForObject("http://YST-RIBBON-ONE/ribbon/demo",String.class);
    }
}

两个微服务:

package com.yst.ystribbonone.rest;

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

/**
 * @program: yst-parent
 * @description: mmh
 * @author: Mr.Miao
 * @create: 2018-08-28 17:21
 **/
@RestController
@RequestMapping("/ribbon")
public class OneController {
    @GetMapping("/demo")
    public String getName(){
        System.out.println("demo1");
        return "demo1";
    }
}

 Two跟这个Controller一样

注意两个微服务的spring.application.name必须一致 调用者(test)与  被调用者(one,two)都需要注册到Eureka。

访问http://localhost:9001/test/getName  这里的9001为调用者端口号

结果我们会发现请求进入 one 和 two 这两个微服务并起到负载的作用。

Ribbon还用很多配置在application.yml里配置:

ribbon:
  eureka:
    enabled: true # 开启Eureka
  ReadTimeout: 100000 # 读取超时时间
  ConnectTimeout: 100000 # 
  MaxAutoRetries: 0
  MaxAutoRetriesNextServer: 1
  OkToRetryOnAllOperations: false

Ribbon规则的配置:

在开始之前,首先说明一下,Ribbon有两种配置,一种是配置文件配置,一种是代码配置,还有的话就是默认的

1、轮询规则 RoundRobinRule 此规则只是通过循环选择服务器。它通常用作默认规则或更高级规则的后备。

2、根据服务是否死掉或者服务处于高并发来分配权重 AvailabilityFilteringRule 此规则将跳过被视为“电路跳闸”或具有高并发连接数的服务器。默认情况下,如果RestClient最近三次无法与其建立连接,则实例会跳闸。一旦实例电路跳闸,它将在电路被认为再次关闭之前保持这种状态30秒。然而,如果它继续连接失败,它将再次“电路跳闸”并且它变为“电路闭合”的等待时间将指数地增加到连续故障的数量。
3、根据响应时间分配权重 WeightedResponseTimeRule 对于此规则,每个服务器根据其平均响应时间给予权重。响应时间越长,重量就越小。该规则随机选择服务器,其中可能性由服务器的权重决定。要启用WeightedResponseTimeRule,请通过API使用负载均衡器进行设置
4、随机原则 RandomRule 

(一)配置文件配置:

  例:

service-B.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule # service-B是注册到Eureka的serviceID 那个大写的东东 千万别写成application.name了

(二)代码自定义配置:

例:

我们都知道@SpringBootApplication注解里有 @ComponentScan自动扫描组件,官方不推荐我们把config放入SpringBoot自动扫描的范围内。所以我们在扫描范围外创建了config文件夹:

微服务框架入门(一)

TestConfiguration类如下:

package com.yst.test.config;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @program: yst-parent
 * @description: mmh
 * @author: Mr.Miao
 * @create: 2018-08-29 13:52
 **/
@Configuration
public class TestConfiguration {
    @Bean
    public IRule ribbonRule(){
        // 随机规则 这里可以定义其他规则
        return new RandomRule();
    }
}

启动类增加注解:

@RibbonClient(name = "Eureka的serviceID",configuration = TestConfiguration.class)

name为注册到Eureka的serviceID,configuration为刚创建的config

多个client可以使用@RibbonClients() 里面value 可以放多个@RibbonClient()

启动即可 其他规则自行测试。

这里总结一下,个人推荐配置文件的配置的方法,省去过多步骤,如果有需要更加灵活的规则,可以使用代码注入Bean的方式。

优先级:配置文件>代码>默认

接下来小伙伴们都知道,如何使用Ribbon了,但是我们发现如果项目中不使用Eureka,我们还有办法使用Ribbon吗?

答案是可以的,请继续看教程:

如何使Eureka 与 Ribbon 分离?

特别简单 只需要在 application.yml 中配置下面一段配置即可

ribbon:
  eureka:
   enabled: false
YST-RIBBON-ONE:   # 这里是还是服务名
  ribbon:
    listOfServers: localhost:9002  # 这里自定义也就是被请求者的地址 多个地址可以用 , 号隔开

我们可以直接使用Ribbon的Api:

public class MyClass {
    @Autowired
    private LoadBalancerClient loadBalancer;

    public void doStuff() {
        ServiceInstance instance = loadBalancer.choose("stores");
        URI storesUri = URI.create(String.format("http://%s:%s", instance.getHost(), instance.getPort()));
        // ... do something with the URI
    }
}

本章完 下节继续