Spring Cloud分区发布实践(2) 微服务
我们准备一下用于查询姓名的微服务.
首先定义一下服务的接口, 新建一个空的Maven模块hello-remotename-core, 里面新建一个类:
public interface RemoteNameService {
String readName(int id) ;
}
接下来的微服务都实现这个简单的接口作为示范.
然后创建一个服务模块hello-remotename, 依然使用 Spring Initializr, 选择 "Spring Web", "Eureka Discovery Client" 2个模块.
其中的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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.cnscud.betazone</groupId>
<artifactId>betazone-root</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<artifactId>hello-remotename</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>hello-remotename</name>
<description>Demo project for Spring Boot</description>
<dependencies>
<dependency>
<groupId>com.cnscud.betazone</groupId>
<artifactId>hello-remotename-core</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<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>
</dependencies>
</project>
此模块依赖接口模块, 用于实现接口. 然后我们实现一个服务的Controller, 如下:
package com.cnscud.betazone.helloremotename.controller;
import com.cnscud.betazone.helloremotename.core.service.RemoteNameService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("remote")
public class RemoteNameServiceController implements RemoteNameService {
private static Logger logger = LoggerFactory.getLogger(RemoteNameServiceController.class);
@Autowired
Environment environment;
final static String defaultName = "guest";
static Map<Integer, String> names = new HashMap<>();
static {
names.put(1, "Felix");
names.put(2, "World");
names.put(3, "Sea");
names.put(4, "Sky");
names.put(5, "Mountain");
}
@Override
@RequestMapping("/id/{id}")
public String readName(@PathVariable("id") int id) {
if( names.get(id) == null ) {
return defaultName + getServerName();
}
else
{
return names.get(id) + getServerName();
}
}
public String readServicePort() {
return environment.getProperty("local.server.port");
}
public String readServiceIp() {
InetAddress localHost = null;
try {
localHost = Inet4Address.getLocalHost();
}
catch (UnknownHostException e) {
logger.error(e.getMessage(), e);
}
return localHost.getHostAddress(); // 返回格式为:xxx.xxx.xxx
}
public String getServerName() {
return " [remotename: " + readServiceIp() + ":" + readServicePort() + "]";
}
}
RemoteNameServiceController实现了RemoteNameService 接口, 为了后续方便区分是哪个实例在服务, 返回的信息里增加了IP和端口信息.
然后声明application.yml, 在9001端口启动
server:
port: 9001
spring:
application:
name: betazone-hello-remotename
eureka:
instance:
prefer-ip-address: true
metadata-map:
zone: main #服务区域
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:8001/eureka/
logging:
level:
org.springframework.cloud: debug
可以看到, 此实例端口为9001, 服务区域zone设置为 main.
然后在复制一个为 application-beta.yml, 修改如下
server:
port: 9002
spring:
application:
name: betazone-hello-remotename
eureka:
instance:
prefer-ip-address: true
metadata-map:
zone: beta #服务区域
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:8001/eureka/
logging:
level:
org.springframework.cloud: debug
此实例设置端口为9002, 服务区域为 beta.
启动第一个Application, 然后复制配置, 修改profile为beta , 启动第二个实例.
此时去Eureka查看, 可以看到betazone-hello-remotename有2个服务, 使用xml查看 http://localhost:8001/eureka/apps , 可以看到不同的metadata.

点击访问 http://localhost:9001/remote/id/2 或 http://localhost:9002/remote/id/2 则可以看到我们刚刚运行的服务.
项目代码: https://github.com/cnscud/javaroom/tree/main/betazone2/hello-remotename
接下来我们看看使用gateway代理服务的效果...
Spring Cloud分区发布实践(2) 微服务的更多相关文章
- Spring Cloud分区发布实践(6)--灰度服务-根据Header选择实例区域
此文是一个完整的例子, 包含可运行起来的源码. 此例子包含以下部分: 网关层实现自定义LoadBalancer, 根据Header选取实例 服务中的Feign使用拦截器, 读取Header Feign ...
- Spring Cloud分区发布实践(1) 环境准备
最近研究了一下Spring Cloud里面的灰度发布, 看到各种各样的使用方式, 真是纷繁复杂, 眼花缭乱, 不同的场景需要不同的解决思路. 那我们也来实践一下最简单的场景: 区域划分: 服务分为be ...
- Spring Cloud分区发布实践(4) FeignClient
上面看到直接通过网关访问微服务是可以实现按区域调用的, 那么微服务之间调用是否也能按区域划分哪? 下面我们使用FeignClient来调用微服务, 就可以配合LoadBalancer实现按区域调用. ...
- Spring Cloud分区发布实践(3) 网关和负载均衡
注意: 因为涉及到配置测试切换, 中间环节需按此文章操作体验, 代码仓库里面的只有最后一步的代码 准备好了微服务, 那我们就来看看网关+负载均衡如何一起工作 新建一个模块hello-gateway, ...
- Spring Cloud分区发布实践(5)--定制ServiceInstanceListSupplier
现在我们简单地来定制二个 ServiceInstanceListSupplier, 都是zone-preference的变种. 为了方便, 我重新调整了一下项目的结构, 把一些公用的类移动到hello ...
- 基于Spring Cloud和Netflix OSS构建微服务,Part 2
在上一篇文章中,我们已使用Spring Cloud和Netflix OSS中的核心组件,如Eureka.Ribbon和Zuul,部分实现了操作模型(operations model),允许单独部署的微 ...
- 今天介绍一下自己的开源项目,一款以spring cloud alibaba为核心的微服务架构项目,为给企业与个人提供一个零开发基础的微服务架构。
LaoCat-Spring-Cloud-Scaffold 一款以spring cloud alibab 为核心的微服务框架,主要目标为了提升自己的相关技术,也为了给企业与个人提供一个零开发基础的微服务 ...
- spring cloud 入门,看一个微服务框架的「五脏六腑」
Spring Cloud 是一个基于 Spring Boot 实现的微服务框架,它包含了实现微服务架构所需的各种组件. 注:Spring Boot 简单理解就是简化 Spring 项目的搭建.配置.组 ...
- 使用 Spring Cloud Stream 构建消息驱动微服务
相关源码: spring cloud demo 微服务的目的: 松耦合 事件驱动的优势:高度解耦 Spring Cloud Stream 的几个概念 Spring Cloud Stream is a ...
随机推荐
- CMD批处理(1)——批处理常用命令总结
echo 打开回显或关闭回显功能,或显示消息.如果没有任何参数,echo命令将显示当前的回显设置. 命令格式1:echo [{on|off}] 命令格式2:echo [message] 例.在命令 ...
- gRPC(2):四种基本通信模式
在 gRPC(1):入门及简单使用(go) 中,我们实现了一个简单的 gRPC 应用程序,其中双方通信是简单的请求-响应模式,没发出一个请求都会得到一个响应,然而,借助 gRPC 可以实现不同的通信模 ...
- 快来为你的 .NET 应用加个监控吧!
导读 CZGL.ProcessMetrics 是一个 Metrics 库,能够将程序的 GC.CPU.内存.机器网络.磁盘空间等信息记录下来,使用 Prometheus 采集信息,然后使用 Grafa ...
- 22、lnmp_nginx反向代理(负载均衡)、高可用
负载均衡,根据ip和端口号找到相应的web服务器站点(即端口区分): 22.1.nginx的负载均衡: 1.介绍: 网站的访问量越来越大,服务器的服务模式也得进行相应的升级,比如分离出数据库服务器.分 ...
- 同步工具——Exchanger
本博客系列是学习并发编程过程中的记录总结.由于文章比较多,写的时间也比较散,所以我整理了个目录贴(传送门),方便查阅. 并发编程系列博客传送门 本文是转载文章,原文请见这里 一.Exchanger简介 ...
- Cable TV Network 顶点连通度 (最大流算法)
Cable TV Network 题目抽象:给出含有n个点顶点的无向图,给出m条边.求定点联通度 K 算法:将每个顶点v拆成 v' v'' ,v'-->v''的容量为1. ...
- A Simple Math Problem 矩阵打水题
A Simple Math Problem Lele now is thinking about a simple function f(x).If x < 10 f(x) = x.If x & ...
- Flask(5)- 动态路由
前言 前面几篇文章讲的路由路径(rule)都是固定的,就是一个路径和一个视图函数绑定,当访问这条路径时会触发相应的处理函数 这样无法处理复杂的情况,比如常见的一个课程分类下有很多个课程,那么他们的 p ...
- AcWing 100. 增减序列
给定一个长度为n的数列每次可以选择一个区间 [l,r],使下标在这个区间内的数都加一或者都减一. 求至少需要多少次操作才能使数列中的所有数都一样,并求出在保证最少次数的前提下,最终得到的数列可能有多少 ...
- JUnit5的条件测试、嵌套测试、重复测试
条件测试 JUnit5支持条件注解,根据布尔值判断是否执行测试. 自定义条件 @EnabledIf和@DisabledIf注解用来设置自定义条件,示例: @Test @EnabledIf(" ...