目录
2.2 loadbalancer负载均衡、feign声明式服务调用
一、微服务搭建
1.1 服务提供者与服务消费者
服务提供者 | 服务的被调用方(即:为其他微服务提供接口的微服务) |
服务消费者 | 服务的调用方(即:调用其他微服务接口的微服务) |
就以图(仅供娱乐,无不良影响)为例搭建一个简单的微服务项目,可以看到一下项目结构:
1.2 依赖关系
1、cloud顶级模块pom文件 (完整) :
<?xml version="1.0" encoding="utf-8"?>
<project xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
xmlns="http://maven.apache.org/pom/4.0.0"
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>org.example</groupid>
<artifactid>cloud</artifactid>
<version>1.0-snapshot</version>
<packaging>pom</packaging>
<!--定义子模块-->
<modules>
<module>ikun</module>
<module>basketball</module>
<module>common</module>
</modules>
<!--依赖版本-->
<properties>
<spring-boot.version>2.4.2</spring-boot.version>
<spring-cloud.version>2020.0.1</spring-cloud.version>
<spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version>
</properties>
<dependencies>
<!--nacos服务注册-->
<dependency>
<groupid>com.alibaba.cloud</groupid>
<artifactid>spring-cloud-starter-alibaba-nacos-discovery</artifactid>
</dependency>
<!--orika是java bean映射框架,可以实现从一个对象递归拷贝数据至另一个对象。-->
<dependency>
<groupid>ma.glasnost.orika</groupid>
<artifactid>orika-core</artifactid>
<version>1.4.6</version>
</dependency>
<!--提供负载均衡的支持-->
<dependency>
<groupid>org.springframework.cloud</groupid>
<artifactid>spring-cloud-loadbalancer</artifactid>
</dependency>
<!--简化 java 代码的工具库-->
<dependency>
<groupid>org.projectlombok</groupid>
<artifactid>lombok</artifactid>
</dependency>
<!--开启负载均衡-->
<dependency>
<groupid>org.springframework.cloud</groupid>
<artifactid>spring-cloud-starter-openfeign</artifactid>
</dependency>
</dependencies>
<!--声明的依赖版本号可以被子模块引用,但不会自动引入这些依赖-->
<dependencymanagement>
<dependencies>
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-dependencies</artifactid>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupid>org.springframework.cloud</groupid>
<artifactid>spring-cloud-dependencies</artifactid>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupid>com.alibaba.cloud</groupid>
<artifactid>spring-cloud-alibaba-dependencies</artifactid>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencymanagement>
</project>
在父级中指定了子模块,子模块需要引用父级模块就能同步使用父级依赖,这样就可以把所有子模块共同依赖同意管理。
2、ikun子模块pom: (basketball如同)
<?xml version="1.0" encoding="utf-8"?>
<project xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns="http://maven.apache.org/pom/4.0.0"
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>
<groupid>com.example</groupid>
<artifactid>ikun</artifactid>
<version>0.0.1-snapshot</version>
<!--引用父模块依赖-->
<parent>
<groupid>org.example</groupid>
<artifactid>cloud</artifactid>
<version>1.0-snapshot</version>
</parent>
<dependencies>
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-web</artifactid>
</dependency>
<!--引入公共模块-->
<dependency>
<groupid>org.example</groupid>
<artifactid>common</artifactid>
<version>1.0-snapshot</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupid>org.apache.maven.plugins</groupid>
<artifactid>maven-compiler-plugin</artifactid>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>utf-8</encoding>
</configuration>
</plugin>
<plugin>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-maven-plugin</artifactid>
<version>${spring-boot.version}</version>
<configuration>
<mainclass>com.example.ikun.ikunapplication</mainclass>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
二、服务注册与负载均衡使用
以上的操作只是建造了一个空壳,我们需要通过一些组件来继续完善微服务体系结构。
2.1 nacos 实现服务的注册与发现
1、添加依赖
<dependency>
<groupid>com.alibaba.cloud</groupid>
<artifactid>spring-cloud-starter-alibaba-nacos-discovery</artifactid>
</dependency>
2、配置服务提供者,从而服务提供者可以通过 nacos 的服务注册发现功能将其服务注册到 nacos server 上。
basketball(服务提供者)配置nacos server 的地址:
server:
port: 8080
spring:
cloud:
nacos:
server-addr: localhost:8848
application:
name: basketball
通过 spring cloud 原生注解 @enablediscoveryclient
开启服务注册发现功能:
package com.example.basketball;
import org.springframework.boot.springapplication;
import org.springframework.boot.autoconfigure.springbootapplication;
import org.springframework.cloud.client.discovery.enablediscoveryclient;
import org.springframework.cloud.openfeign.enablefeignclients;
@springbootapplication
@enablediscoveryclient
@enablefeignclients
public class basketballapplication {
public static void main(string[] args) {
springapplication.run(basketballapplication.class, args);
}
}
3、配置服务消费者,从而服务消费者可以通过 nacos 的服务注册发现功能从 nacos server 上获取到它要调用的服务。
ikun(服务消费者)中配置 nacos server 的地址:
server:
port: 8081
spring:
cloud:
nacos:
server-addr: localhost:8848
application:
name: ikun
通上在启动类上添加 spring cloud 原生注解 @enablediscoveryclient
开启服务注册发现功能。
2.2 loadbalancer负载均衡、feign声明式服务调用
因为两个子模块都需要此组件,所以直接在父模块cloud添加负载均衡依赖:
<!--提供负载均衡的支持-->
<dependency>
<groupid>org.springframework.cloud</groupid>
<artifactid>spring-cloud-loadbalancer</artifactid>
</dependency>
<!--远程服务通信-->
<dependency>
<groupid>org.springframework.cloud</groupid>
<artifactid>spring-cloud-starter-openfeign</artifactid>
</dependency>
在两个子模块启动类添加注释开启服务通信
@enablefeignclients
2.3 示例综合实现
那么所有配置都已搭建好,接下来编写api接口来实现服务通信与负载均衡:
1、准备一个实体与dto类,因为本次示例并没有连接数据库,仅仅编写一个类用于实例化数据。这里我准备了一个公共模块(common)用来放置公共所需的类
package pojo.dto;
import lombok.allargsconstructor;
import lombok.data;
import lombok.noargsconstructor;
/**
* @author 云村小威
* @create 2024-01-06 15:52
*/
@data
@noargsconstructor
@allargsconstructor
public class ikundto {
private long id;
private string account;
private string password;
private integer age;
private string hobby;
}
消费者 远程调用 生产者 : 需要网络传输,使用dto同一封装对象 原理与springboot启动类相同
- 将dto对象封装到公共dto模块
- 为需要的项目引入公共dto模块
<!--引入公共模块-->
<dependency>
<groupid>org.example</groupid>
<artifactid>common</artifactid>
<version>1.0-snapshot</version>
</dependency>
2、服务提供者(basketball)
提供接口方法和返回结果
package com.example.basketball.controller;
import pojo.dto.ikundto;
import lombok.extern.slf4j.slf4j;
import org.springframework.web.bind.annotation.*;
import java.util.map;
@slf4j
@restcontroller
@requestmapping("/kun")
public class cxkcontroller {
@requestmapping("/{account}")
public string getbypath(@pathvariable string account) {
log.info("account:" + account);
return "kun : 唱";
}
@requestmapping("/param")
public string getbyparam(@requestparam("account") string account,
@requestparam("password") string password) {
log.info("param:" + account + "\t" + password);
return "kun : 跳";
}
@requestmapping("/pojo")
public string getbypojo(@requestbody ikundto ikundto) {
log.info("dto:" + ikundto);
return "kun : rep";
}
@requestmapping("/more")
public string getbymore(@requestbody map<string, object> map) {
log.info("more:" + map);
return "🏀";
}
}
3、服务消费者(ikun)
i. 创建server,并使用feign表示其需要远程对接的服务名称,并使用@requestmapping表示其映射的 路径
package com.example.ikun.serice;
import pojo.dto.ikundto;
import org.springframework.cloud.openfeign.feignclient;
import org.springframework.web.bind.annotation.pathvariable;
import org.springframework.web.bind.annotation.requestbody;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.requestparam;
import java.util.map;
/**
* 连接生产者 controller
*
* @author 云村小威
* @create 2024-01-06 15:40
*/
@feignclient("basketball") //连接服务器名称(服务提供者yml设置)
@requestmapping("/kun")
public interface feginkunservice {
@requestmapping("/{account}")
public string getbypath(@pathvariable(value = "account") string account);
@requestmapping("/param")
public string getbyparam(@requestparam("account") string account,
@requestparam("password") string password);
@requestmapping("/pojo")
public string getbypojo(@requestbody ikundto ikundto);
@requestmapping("/more")
public string getbymore(@requestbody map<string, object> map);
}
ii. 消费者行为接口测试
package com.example.ikun.controller;
import com.example.ikun.serice.feginkunservice;
import pojo.dto.ikundto;
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.restcontroller;
import java.util.hashmap;
import java.util.map;
@restcontroller
public class testcontroller {
@autowired
private feginkunservice kunservice;
@requestmapping("/play01")
public string play() {
return kunservice.getbypath("姬霓太美");
}
@requestmapping("/play02")
public string play02() {
return kunservice.getbyparam("小黑子", "123");
}
@requestmapping("/play03")
public string play03() {
return kunservice.getbypojo(new ikundto(1l, "纯路人", "123", 5 / 2, "music"));
}
@requestmapping("/play04")
public string play04() {
map<string, object> parammap = new hashmap<>();
parammap.put("真爱粉", new ikundto(2l, "梅丽猫", "321", 5 / 2, "唱、跳、rep、篮球"));
return kunservice.getbymore(parammap);
}
}
iii. 先启动nacos服务、在启动项目
这里注意nacos默认为集群模式,本次示例并没有连接数据库,所以要修改为单机模式启动
接着输入nacos地址进行登录,账号与密码默认为:nacos
接着就可以看到已注册的服务
最后接口测试:
2.3.1 服务注册与发现测试
2.3.2 负载均衡测试
为了更好体现负载均衡的作用,这里将basketball与ikun两个模块进行打包运行测试
发表评论