SpringBoot 는 Netty 를 사용 하여 원 격 호출 을 실현 하 는 예제 입 니 다.
9962 단어 SpringBootNetty원 격 호출
알다 시 피 우리 가 네트워크 연결 을 할 때 소켓 연결 을 구축 하 는 것 은 매우 성능 을 소모 하 는 일이 다.특히 분포 식 상황 에서 스 레 드 풀 로 여러 클 라 이언 트 연결 을 유지 하 는 것 은 스 레 드 를 매우 소모 하 는 행위 이다.그렇다면 우 리 는 어떤 기술 을 통 해 상술 한 문 제 를 해결 해 야 합 니까?그러면 네트워크 연결 의 이기 인
Netty
을 제기 해 야 합 니까?본문 Netty
Netty 는
NIO
클 라 이언 트 서버 프레임 워 크 입 니 다.TCP
과UDP
소켓 서버 등 이다.NIO
는 비 차단IO
으로 다음 과 같은 특징 을 가진다.Channel
,새로운 채널 은 모두 선택 기 에 등록 해 야 합 니 다.SelectionKey
키 는 특정한 채널 대상 과 특정한 선택 기 대상 간 의 등록 관 계 를 나타 낸다.selector
작업 을 하면 차단 이 생 길 수 있 지만 차단 시간 을 설정 할 수 있 고select()
로 깨 울 수 있 기 때문에wakeup()
시비 차단selector
그것 은 일반
NIO
에 비해 성능 이 향상 되 었 고 사용 되 었 다.IO
다 중 스 레 드 방식 으로 여러 개NIO
NIO
가 여러 개selector
selector
만 있 을 수 있 고ServerSocketServer
의 일치 와 재 활용 을 실현 할 수 있다.![在这里插入图片描述](https://s1.md5.ltd/image/92b2ffa7ef4ebe715fa11f38693796f8.png)
문제
selector
메 시 지 를 보 낼 때 가방 을 뜯 을 수 있 기 때문에 수신 자 는 언제 받 은 데이터 가 완전한 데이터 인지 알 수 없다.전통 적 인Channel
에서 데 이 터 를 읽 지 못 할 때 차단 이 발생 하지만TCP/IP
그렇지 않 습 니 다.BIO
의 패키지 문 제 를 해결 하기 위해NIO
모델 을 바탕 으로NIO
모델 을 제시 하여 클 라 이언 트 가 서버 에서 불완전 하 게 요구 하 는 문 제 를 해결 했다.netty 모델 reactor 모드
Netty
을 바탕 으로 반 가방 문 제 를 해결 했다.![在这里插入图片描述](https://s1.md5.ltd/image/cdff966206bcddf1e5f34b9d572b37f7.png)
위의 그림 은 간단하게'boss 가 일 을 맡 고 work 를 하 게 합 니 다'라 고 묘사 할 수 있 습 니 다.
Selector
요청 을 받 는 데 사 용 됩 니 다(클 라 이언 트 와 악수 검증 을 할 것 입 니 다).reactor
요청 을 처리 하 는 데 사 용 됩 니 다(클 라 이언 트 와 직접 연결 하지 않 습 니 다).SpringBoot 는 Netty 를 사용 하여 원 격 호출 을 실현 합 니 다.
maven 의존
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.2</version>
<optional>true</optional>
</dependency>
<!--netty-->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.17.Final</version>
</dependency>
서버 부분NettyServer.java:서비스 시작 모니터
@Slf4j
public class NettyServer {
public void start() {
InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1", 8082);
//new
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
//new
EventLoopGroup workGroup = new NioEventLoopGroup(200);
ServerBootstrap bootstrap = new ServerBootstrap()
.group(bossGroup, workGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ServerChannelInitializer())
.localAddress(socketAddress)
//
.option(ChannelOption.SO_BACKLOG, 1024)
// ,TCP
.childOption(ChannelOption.SO_KEEPALIVE, true);
// ,
try {
ChannelFuture future = bootstrap.bind(socketAddress).sync();
log.info(" : {}", socketAddress.getPort());
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
log.error(" ", e);
} finally {
//
bossGroup.shutdownGracefully();
//
workGroup.shutdownGracefully();
}
}
}
ServerChannel Initializer.java:selector
서비스 초기 화 기
/**
* netty
**/
public class ServerChannelInitializer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
//
socketChannel.pipeline().addLast("decoder", new StringDecoder(CharsetUtil.UTF_8));
socketChannel.pipeline().addLast("encoder", new StringEncoder(CharsetUtil.UTF_8));
socketChannel.pipeline().addLast(new NettyServerHandler());
}
}
NettyServerHandler.java:manReactor
서버 프로세서
/**
* netty
**/
@Slf4j
public class NettyServerHandler extends ChannelInboundHandlerAdapter {
/**
*
*/
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
log.info("Channel active......");
}
/**
*
*/
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
log.info(" : {}", msg.toString());
ctx.write(" ");
ctx.flush();
}
/**
*
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
RpcServerApp.java:subReactor
시작 클래스
/**
*
*
*/
@Slf4j
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class RpcServerApp extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(RpcServerApp.class);
}
/**
*
*
* @param args
*/
public static void main(String[] args) {
SpringApplication.run(RpcServerApp.class, args);
// Netty
NettyServer nettyServer =new NettyServer ();
nettyServer.start();
log.info("====== ========");
}
}
클 라 이언 트 부분NettyClient Util.java:
netty
도구 클래스
/**
* Netty
**/
@Slf4j
public class NettyClientUtil {
public static ResponseResult helloNetty(String msg) {
NettyClientHandler nettyClientHandler = new NettyClientHandler();
EventLoopGroup group = new NioEventLoopGroup();
Bootstrap bootstrap = new Bootstrap()
.group(group)
// Nagle ,
.option(ChannelOption.TCP_NODELAY, true)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast("decoder", new StringDecoder());
socketChannel.pipeline().addLast("encoder", new StringEncoder());
socketChannel.pipeline().addLast(nettyClientHandler);
}
});
try {
ChannelFuture future = bootstrap.connect("127.0.0.1", 8082).sync();
log.info(" ....");
//
future.channel().writeAndFlush(msg);
//
future.channel().closeFuture().sync();
return nettyClientHandler.getResponseResult();
} catch (Exception e) {
log.error(" Netty ", e);
throw new BusinessException(CouponTypeEnum.OPERATE_ERROR);
} finally {
//
group.shutdownGracefully();
}
}
}
NettyClient Handler.java:클 라 이언 트 프로세서
/**
*
**/
@Slf4j
@Setter
@Getter
public class NettyClientHandler extends ChannelInboundHandlerAdapter {
private ResponseResult responseResult;
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
log.info(" Active .....");
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
log.info(" : {}", msg.toString());
this.responseResult = ResponseResult.success(msg.toString(), CouponTypeEnum.OPERATE_SUCCESS.getCouponTypeDesc());
ctx.close();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
검증 하 다.테스트 인터페이스
@RestController
@Slf4j
public class UserController {
@PostMapping("/helloNetty")
@MethodLogPrint
public ResponseResult helloNetty(@RequestParam String msg) {
return NettyClientUtil.helloNetty(msg);
}
}
액세스 테스트 인터페이스![在这里插入图片描述](https://s1.md5.ltd/image/336212c8be69b55c04a88102ef0b5d38.png)
서버 인쇄 정보
![在这里插入图片描述](https://s1.md5.ltd/image/f0f9b6644f1142392cf645c4f9799d53.png)
클 라 이언 트 인쇄 정보
![在这里插入图片描述](https://s1.md5.ltd/image/40bfb302141664f99cfaf5b1a288e4f7.png)
소스 코드
프로젝트 원본 코드 는 나의 github 에서 가 져 올 수 있 습 니 다:github 소스 주소
여기 서 SpringBoot 가 Netty 를 사용 하여 원 격 호출 을 실현 하 는 예제 에 관 한 글 은 여기까지 소개 되 었 습 니 다.더 많은 SpringBoot Netty 원 격 호출 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 응원 바 랍 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
【Java・SpringBoot・Thymeleaf】 에러 메세지를 구현(SpringBoot 어플리케이션 실천편 3)로그인하여 사용자 목록을 표시하는 응용 프로그램을 만들고, Spring에서의 개발에 대해 공부하겠습니다 🌟 마지막 데이터 바인딩에 계속 바인딩 실패 시 오류 메시지를 구현합니다. 마지막 기사🌟 src/main/res...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.