我是靠谱客的博主 无语大侠,最近开发中收集的这篇文章主要介绍Springcloud Alibaba详细入门教程(四),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

搭建Eureka集群环境

目的:负载均衡、故障容错

如果我们只配置一个Eureka服务端,那么如果这个服务端崩盘,那么所有服务都无法获取,这肯定不是我们不期望的。所以为了保证高可用性,我们需要搭建Eureka集群。

新建子工程cloud-eureka-server7002 ,跟7001子工程一样,只有启动类和yml文件不一致

  • 打开 本地 C:WindowsSystem32driversetchosts 文件

    在最后一行添加如图所示 信息

  • cloud-eureka-server7002.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">
        <parent>
            <artifactId>cloud2020</artifactId>
            <groupId>com.atguigu.springcloud</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.atguigu.springcloud</groupId>
        <artifactId>cloud-eureka-server7002</artifactId>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            </dependency>
            <dependency>
                <groupId>com.atguigu.springcloud</groupId>
                <artifactId>cloud-api-commons</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
                <scope>runtime</scope>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    </project>
  • application.yml

  • server:
      port: 7002
    
    #eureka服务端的实例名称
    eureka:
      instance:
        hostname: eureka7002.com
      client:
        #false表示不向注册中心注册自己
        register-with-eureka: false
        #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去搜索服务
        fetch-registry: false
        service-url:
          #设置与eureka server交互的地址查询服务和注册服务都需要依赖这个地址
    #      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
          defaultZone: http://eureka7001.com:7001/eureka/

    启动类EurekaMain7002.java

  • package com.atguigu.springcloud;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
    
    @SpringBootApplication
    @EnableEurekaServer
    public class EurekaMain7002 {
        public static void main(String[] args) {
            SpringApplication.run(EurekaMain7002.class,args);
        }
    }

    最后修改子工程cloud-eureka-server7001的yml文件

  • server:
      port: 7001
    
    #eureka服务端的实例名称
    eureka:
      instance:
        hostname: eureka7001.com
      client:
        #false表示不向注册中心注册自己
        register-with-eureka: false
        #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去搜索服务
        fetch-registry: false
        service-url:
          #设置与eureka server交互的地址查询服务和注册服务都需要依赖这个地址
    #      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
          defaultZone: http://eureka7002.com:7002/eureka/

    启动子工程 7001 和 7002

    分别访问 http://eureka7001.com:7001/ 和 http://eureka7002.com:7002/

  • 支付Payment8001和订单order80 子工程注册进eureka 7001 和 eureka7002中

    子工程payment8001的yml文件

  • server:
      port: 8001
    spring:
      application:
        name: cloud-payment-service #服务名
      datasource:
        type: com.alibaba.druid.pool.DruidDataSource  #当前数据源操作类型
        driver-class-name: com.mysql.cj.jdbc.Driver #数据库驱动包
        url: jdbc:mysql://localhost:3306/cloud2020?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true
        username: root
        password: root
      devtools:
        restart:
          enabled: true #是否支持热部署
    eureka:
      client:
        #表示是否将自己注册进eurekaServer 默认为true
        register-with-eureka: true
        #是否从eurekaServer抓取已有的注册信息,默认为true,单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
        fetch-registry: true
        service-url:
          defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/erueka
    
    mybatis:
      mapper-locations: classpath:mapper/*.xml
      type-aliases-package: com.atguigu.springcloud.entities  #所有entity别名所在包

    子工程order80的yml文件

  • server:
      port: 80
    
    spring:
      application:
        name: cloud-order-service
    eureka:
      client:
        #表示是否将自己注册进eurekaServer 默认为true
        register-with-eureka: true
        fetch-registry: true
        service-url:
          defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/erueka

    启动测试:先启动eureka7001工程和eureka7002工程,再启动payment8001工程,最后启动order80工程

    Postman访问: http://localhost:80/consumer/payment/get/3  成功

支付Payment8002子工程集群搭建,新建cloud-provider-payment8002子工程

cloud-provider-payment8002.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">
    <parent>
        <artifactId>cloud2020</artifactId>
        <groupId>com.atguigu.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.atguigu.springcloud</groupId>
    <artifactId>cloud-provider-payment8002</artifactId>


    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.2</version>
        </dependency>
        <dependency>
            <groupId>com.atguigu.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>
</project>

application.yml

server:
  port: 8002
spring:
  application:
    name: cloud-payment-service #服务名
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource  #当前数据源操作类型
    driver-class-name: com.mysql.cj.jdbc.Driver #数据库驱动包
    url: jdbc:mysql://localhost:3306/cloud2020?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true
    username: root
    password: root
  devtools:
    restart:
      enabled: true #是否支持热部署
eureka:
  client:
    #表示是否将自己注册进eurekaServer 默认为true
    register-with-eureka: true
    #是否从eurekaServer抓取已有的注册信息,默认为true,单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
    fetch-registry: true
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/erueka

mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.atguigu.springcloud.entities  #所有entity别名所在包

启动类PaymentMain8002.java

package com.atguigu.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

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

业务类完全一样,从payment8001子工程复制到payment8002子工程

同理,右键打开子工程payment8001的controller所在目录

修改Payment8001子工程和Payment8002子工程的controller文件,两个文件修改内容一样,加入引入application.yml的端口,使用@Value注解来引入

@Value("${server.port}")
private String serverPort;

Payment8001子工程的controller:

package com.atguigu.springcloud.controller;

import com.atguigu.springcloud.entities.CommonResult;
import com.atguigu.springcloud.entities.Payment;
import com.atguigu.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

@Slf4j
@RestController
@RequestMapping("/payment")
public class PaymentController {

    @Resource
    private PaymentService paymentService;

    @Value("${server.port}")
    private String serverPort;

    @PostMapping(value = "/create")
    public CommonResult create(@RequestBody Payment payment){
        int result=paymentService.create(payment);
        log.info("****=插入结果:"+result);
        if (result>0){
            return new CommonResult(200,"插入数据库成功,端口号为:"+serverPort,result);
        }else {
            return new CommonResult(444,"插入数据库失败",null);
        }
    }

    //通过id进行查询
    @GetMapping("/get/{id}")
    public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id ){
        Payment payment = paymentService.getPaymentById(id);
        log.info("****查询结果:"+payment);
        if (payment != null){
            return new CommonResult(200,"查询成功,端口号为:"+serverPort,payment);
        }else {
            return new CommonResult(444,"没有对应记录,查询ID:"+id,null);
        }
    }
}

Payment8002子工程的controller

package com.atguigu.springcloud.controller;

import com.atguigu.springcloud.entities.CommonResult;
import com.atguigu.springcloud.entities.Payment;
import com.atguigu.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

@Slf4j
@RestController
@RequestMapping("/payment")
public class PaymentController {

    @Resource
    private PaymentService paymentService;

    @Value("${server.port}")
    private String serverPort;

    @PostMapping(value = "/create")
    public CommonResult create(@RequestBody Payment payment){
        int result=paymentService.create(payment);
        log.info("****=插入结果:"+result);
        if (result>0){
            return new CommonResult(200,"插入数据库成功,端口号为:"+serverPort,result);
        }else {
            return new CommonResult(444,"插入数据库失败",null);
        }
    }

    //通过id进行查询
    @GetMapping("/get/{id}")
    public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id ){
        Payment payment = paymentService.getPaymentById(id);
        log.info("****查询结果:"+payment);
        if (payment != null){
            return new CommonResult(200,"查询成功,端口号为:"+serverPort,payment);
        }else {
            return new CommonResult(444,"没有对应记录,查询ID:"+id,null);
        }
    }
}

修改order80子工程的OrderController.java,把url改成eureka上的服务名

package com.atguigu.springcloud.controller;

import com.atguigu.springcloud.entities.CommonResult;
import com.atguigu.springcloud.entities.Payment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

@RestController
@Slf4j
public class OrderController {

//    private final static String PAYMENT_URL = "http://localhost:8001";
    private final static String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/consumer/payment/get/{id}")
    public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id) {
        log.info("****开始查询");
        return restTemplate.getForObject(PAYMENT_URL+"/payment/get/"+id,CommonResult.class);
    }

    @GetMapping("/consumer/payment/create")
    public CommonResult<Payment> create(Payment payment) {
        log.info("****开始新增");
        return restTemplate.postForObject(PAYMENT_URL+"/payment/create",payment,CommonResult.class);
    }
}

服务启动:eureka7001->eureka7002->payment8001->payment8002->order80

此时访问 http://localhost:80/consumer/payment/get/1 报500错误

There was an unexpected error (type=Internal Server Error, status=500).

I/O error on GET request for "http://CLOUD-PAYMENT-SERVICE/payment/get/1": CLOUD-PAYMENT-SERVICE; nested exception is java.net.UnknownHostException: CLOUD-PAYMENT-SERVICE

org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://CLOUD-PAYMENT-SERVICE/payment/get/1": CLOUD-PAYMENT-SERVICE; nested exception is java.net.UnknownHostException: CLOUD-PAYMENT-SERVICE

因为我们配置了服务名访问,但是消费者不知道需要从哪台服务访问,需要在o上加入RestTemplate上加入@LoadBalanced开启负载均衡,默认会以轮训的方式加载每一台服务

在order80子工程的config下的ApplicationContextController.java中添加注解

package com.atguigu.springcloud.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class ApplicationContextConfig {

    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
}

之后多次访问postman http://localhost:80/consumer/payment/get/1 ,会依次出现不同的端口号

最后

以上就是无语大侠为你收集整理的Springcloud Alibaba详细入门教程(四)的全部内容,希望文章能够帮你解决Springcloud Alibaba详细入门教程(四)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(62)

评论列表共有 0 条评论

立即
投稿
返回
顶部