Spring Cloud入门系列(二)——服务注册与发现之Eureka(已停更,建议切换到Nacos)
服务注册与发现的定义
Eureka组件
微服务之间如何调用
如何使用
新建服务注册中心
新增模块,名为:cloud-eureka-server7001
该模块就是Eureka注册中心。
EurekaMain7001中的代码如下:
package com.banana.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
/**
* @author layman
* @EnableEurekaServer: 该注解说明自己是EurekaServer
* @date 2021/1/10
*/
@SpringBootApplication
@EnableEurekaServer
public class EurekaMain7001 {
public static void main(String[] args) {
SpringApplication.run(EurekaMain7001.class,args);
}
}
application.yml中的内容,如下:
server:
port: 7001
eureka:
instance:
#eureka服务端的实例名称
hostname: localhost
#hostname: eureka7001.com
client:
#false表示不向注册中心注册自己
register-with-eureka: false
#false表示自己端就是注册中心
fetch-registry: false
service-url:
# #设置 服务的注册地址
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>cloud201230</artifactId>
<groupId>com.banana</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-eureka-server7001</artifactId>
<dependencies>
<!--eureka server-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<!--引入自定义的api通用包,可以使用Payment支付Entity-->
<dependency>
<groupId>com.banana</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- boot web actuator -->
<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>
</dependencies>
</project>
启动Eureka服务端
如果看到以下界面,说明Eureka服务端启动成功。
可以看到,目前 Eureka服务端 里没有注册的服务实例。
接下来,需要注册几个服务 到 Eureka服务端.
新增服务提供者8001
新增模块:cloud-provider-payment8001
该模块,是服务提供者。
PaymentController
package com.banana.springcloud.controller;
import com.banana.springcloud.entity.CommonResult;
import com.banana.springcloud.entity.Payment;
import com.banana.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
* @author layman
* @date 2020/12/30
* @Slf4j :开启日志注解
* @RestController注解 == @ResponseBody + @Controller
* @ResponseBody: 是用来把返回对象自动序列化成HttpResponse的。
* @Controller是: 一种特殊化的@Component类。习惯和@RequestMapping绑定使用,后者是用来指定路由映射。
* 1: 如果只是使用@RestController注解Controller,则Controller中的方法无法返回jsp页面,或者html,
* 配置的视图解析器 InternalResourceViewResolver不起作用,返回的内容就是return 里的内容。
* 可以用做ajax请求数据等
* 2: 如果需要返回到指定页面,则需要用 @Controller配合视图解析器InternalResourceViewResolver才行。
* 如果需要返回JSON,XML或自定义mediaType内容到页面,则需要在对应的方法上加上@ResponseBody注解。
*/
@RestController
@Slf4j
@RequestMapping("/payment")
public class PaymentController {
/* RequestMapping:payment和/payment都能正常访问(规范要加)
加/:绝对路径(根路径),不加/:相对路径*/
@Resource
private PaymentService paymentService;
@Value("${server.port}")
private String serverPort;
/**
* @RequestBody: 接收前端传递给后端的json字符串中的数据(请求体)
* GET方式无请求体(请求参数附带在浏览器的URL里),只有POST请求才有请求体
* RequestBody与RequestParam()可同时使用:一个请求,只有一个RequestBody,但可以有多个RequestParam。
* RequestParam:参数可以是普通元素、数组、集合、对象等等(key-value 类型)
*/
@PostMapping("/create")
public CommonResult create(@RequestBody Payment payment){
int result = paymentService.create(payment);
log.info("****插入结果:"+result);
if(result > 0){
return new CommonResult(200,"插入数据成功,serverPort:"+serverPort,payment.getId());
}
return new CommonResult(400,"插入数据失败");
}
@GetMapping("/get/{id}")
public CommonResult getPaymentById(@PathVariable("id") Long id){
//@PathVariable:路径变量,是spring3.0的新功能,能够接收请求路径中占位符的值
Payment payment = paymentService.getPaymentById(id);
if(payment !=null ){
log.info("****查询结果:"+payment);
return new CommonResult(200,"查询数据成功,serverPort:"+serverPort,payment);
}
return new CommonResult(400,"没有对应的记录,查询id为:"+id);
}
PaymentDao
package com.banana.springcloud.dao;
import com.banana.springcloud.entity.Payment;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface PaymentDao {
// 新增
int create(Payment payment);
// 根据id获取订单
Payment getPaymentById(@Param("id")Long id);
}
PaymentServiceImpl
package com.banana.springcloud.service.impl;
import com.banana.springcloud.dao.PaymentDao;
import com.banana.springcloud.entity.Payment;
import com.banana.springcloud.service.PaymentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* @author layman
* @description: PaymentService的实现类
* @date 2020/12/30
*/
@Service
public class PaymentServiceImpl implements PaymentService {
@Resource
private PaymentDao paymentDao;
@Override
public int create(Payment payment) {
return paymentDao.create(payment);
}
@Override
public Payment getPaymentById(Long id) {
return paymentDao.getPaymentById(id);
}
}
PaymentService
package com.banana.springcloud.service;
import com.banana.springcloud.entity.Payment;
import org.apache.ibatis.annotations.Param;
/**
* @author layman
* @description: service类
* @date 2020/12/30
*/
public interface PaymentService {
int create(Payment payment);
Payment getPaymentById(@Param("id")Long id);
}
PaymentMain8001
package com.banana.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
/**
* @author layman
* @date 2020/12/30
*/
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
public class PaymentMain8001 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8001.class,args);
}
}
PaymentMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.banana.springcloud.dao.PaymentDao">
<resultMap id="BaseResultMap" type="com.banana.springcloud.entity.Payment">
<!-- 定义主键 ,非常重要。如果是多个字段,则定义多个id -->
<!--property是实体类属性名,column是数据库列名-->
<id property="id" column="id" jdbcType="BIGINT" />
<!-- 定义普通属性 -->
<result property="serial" column="serial" jdbcType="VARCHAR"/>
</resultMap>
<!--在主键是自增的情况下,添加成功后可以直接使用主键值,其中keyProperty的值是对象的属性值,不是数据库表中的字段名-->
<insert id="create" parameterType="payment" useGeneratedKeys="true" keyProperty="id">
insert into payment(serial) VALUES (#{serial})
</insert>
<select id="getPaymentById" parameterType="Long" resultMap="BaseResultMap">
select * from payment where id = #{id}
</select>
</mapper>
server:
port: 8001
spring:
application:
name: cloud-payment-service
datasource:
# 当前数据源操作类型
type: com.alibaba.druid.pool.DruidDataSource
# mysql驱动类
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/cloud2020?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8
username: root
password: root
eureka:
client:
#是否将自己注册到注册中心, 默认true
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,单机无所谓,集群必须设置为true配合ribbon使用负载均衡
fetch-registry: true
service-url:
defaultZone: http://localhost:7001/eureka #单机版(将payment8001注册到7001)
# defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka #集群版
instance:
instance-id: payment8001
#访问路径可以显示IP地址
prefer-ip-address: true
#Eureka客户端向服务端发送心跳的时间间隔.单位为秒(默认30 秒)
lease-renewal-interval-in-seconds: 30
#Eureka服务端在收到最后一次心跳等待时间上限.单位为秒(默认90 秒),超时将剔除服务
lease-expiration-duration-in-seconds: 90
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.banana.springcloud.entity
启动8001,刷新Eureka服务端。
可以看到 cloud-payment-service 成功注册到7001 Eureka服务端。