第一章节是主要是服务器启动的代码分析。章节目录有: |---------1.1初始化NioEventLoopGroup |---------1.2初始化NioEventLoop |---------1.3初始化NioServerSocketChannel |---------1.4服务器启动流程 为什么先从初始化开始了解服务器启动? 因为在我看服务器启动的相关源码的时候,有很多地方都是初始化的时候已经建立好的。所以我就从初始化的源码开始看起。这是我第一次看源码的笔记,仍有很多理解错误的地方和不解的地方。欢迎讨论。
本篇目录
启动服务器代码
1 创建NioEventLoopGroup对象。上文已经介绍了NioEventLoopGroup的初始化已经内部线程NioEventLoop的初始化话。
2 创建ServerBootstrap对象,该类初始化主要是创建了几个LinkedHashMap
来存储设置。例如childOptions
或者childAttrs
public void bind() {
//1
EventLoopGroup boss = new NioEventLoopGroup();
EventLoopGroup work = new NioEventLoopGroup();
try {
// 引导绑定和启动服务器
//2
ServerBootstrap b = new ServerBootstrap();
//3
b.group(boss, work);
// 创建NioEventLoopGroup对象来处理事件,如接受新连接、接收数据、写数据等等
//4
b.channel(NioServerSocketChannel.class);
// 设置childHandler执行所有的连接请求
//5
b.childHandler(new ChildChannelHandler());
//6
b.option(ChannelOption.SO_BACKLOG, 100);
//绑定端口
//7
ChannelFuture future = b.bind(8080).sync();
//8
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
//9
boss.shutdownGracefully();
work.shutdownGracefully();
}
}
3 Group
赋值两个线程池。 1 首先第一个boss线程池是赋值到父类AbstractBootstrap
的group变量中。 2 work线程池就赋值在ServerBootstrap的childGroup变量中。
public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup) {
//1
super.group(parentGroup);
if (childGroup == null) {
throw new NullPointerException("childGroup");
}
if (this.childGroup != null) {
throw new IllegalStateException("childGroup set already");
}
this.childGroup = childGroup;
return this;
}
4 channel()
首先ReflectiveChannelFactory
类是一个工厂类,里面只有一个方法newChannel()
用来将传入的class进行无参构造生成对象的。
然后channelFactory()是将ReflectiveChannelFactory赋予ServerBootstrap的父类的channelFactory参数
此时channel 还没被创建,直到bind()方法中调用initAndRegister()
方法的时候才会用该工厂类生成一个channel。下文会讲。
public B channel(Class channelClass) {
if (channelClass == null) {
throw new NullPointerException("channelClass");
}
return channelFactory(new ReflectiveChannelFactory(channelClass));
}
5 childHandler()
在调用这个childHandler()
这个方法的时候,你需要自己写一个方法继承ChannelInitializer类
。而ChannelInitializer
类也是继承ChannelInboundHandlerAdapter
的。所以childHandler()
方法的参数就是我们自己写的类。然后赋值到childHandler参数。
public ServerBootstrap childHandler(ChannelHandler childHandler) {
if (childHandler == null) {
throw new NullPointerException("childHandler");
}
this.childHandler = childHandler;
return this;
}
6 Option()
将一些配置存储到options变量中,该变量是一个LinkedHashMap
public B option(ChannelOption option, T value) {
if (option == null) {
throw new NullPointerException("option");
}
if (value == null) {
synchronized (options) {
options.remove(option);
}
} else {
synchronized (options) {
options.put(option, value);
}
}
return (B) this;
}
7 bind()
之前的一些方法都只是对ServerBootstrap的配置,说白了就是用来set参数的。 bind()则是开始启动服务器了。
1 进行对group
和channelFactory
两个参数进行非空验证
public ChannelFuture bind(SocketAddress localAddress) {
validate(); //1
if (localAddress == null) {
throw new NullPointerException("localAddress");
}
return doBind(localAddress);
}
doBind()
1 创建一个channel 并且初始化和注册。关键部分。代码分析看下面
2 判断channel是否注册成功。如果已经注册成功那么就进行doBind0()
方法。如果还没成功,那就添加一个监听器,等返回成功的时候就进行doBind0()
方法。解析看下文。
private ChannelFuture doBind(final SocketAddress localAddress) {
final ChannelFuture regFuture = initAndRegister(); //1
final Channel channel = regFuture.channel();
if (regFuture.cause() != null) {
return regFuture;
}
//2
if (regFuture.isDone()) {
ChannelPromise promise = channel.newPromise();
doBind0(regFuture, channel, localAddress, promise);
return promise;
} else {
final PendingRegistrationPromise promise = new PendingRegistrationPromise(channel);
regFuture.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
Throwable cause = future.cause();
if (cause != null) {
promise.setFailure(cause);
} else {
promise.registered();
doBind0(regFuture, channel, localAddress, promise);
}
}
});
return promise;
}
}
doBind0()
1 该方法是执行在channel已经与selector注册后的。给线程添加一个任务。该任务是绑定端口的。
到这个方法。服务器启动就已经完成了
private static void doBind0(
final ChannelFuture regFuture, final Channel channel,
final SocketAddress localAddress, final ChannelPromise promise) {
//1
channel.eventLoop().execute(new Runnable() {
@Override
public void run() {
if (regFuture.isSuccess()) {
channel.bind(localAddress, promise).addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
} else {
promise.setFailure(regFuture.cause());
}
}
});
}
下文都是对initAndRegister()
方法的代码解析
initAndRegister()
1 利用工厂创建一个channel对象。初始化内容看上一篇文章初始化NioServerSocketChannel
2 对channel进行一个初始化,看下文。
3 对channel进行注册,看下文
final ChannelFuture initAndRegister() {
Channel channel = null;
try {
//1
channel = channelFactory.newChannel();
//2
init(channel);
} catch (Throwable t) {
}
//3
ChannelFuture regFuture = config().group().register(channel);
if (regFuture.cause() != null) {
if (channel.isRegistered()) {
channel.close();
} else {
channel.unsafe().closeForcibly();
}
}
return regFuture;
}
init()
1 对channel 的config变量里添加options属性
2 对channel 的config变量里添加attrs属性
3 获取channel 对象的pipeline管道,然后在管道里面添加一个handler,该handler作用有:添加bootstrap里的handler。对channel 添加一个任务。
4 添加bootstrap里的handler。对channel 添加一个任务
void init(Channel channel) throws Exception {
final Map, Object> options = options0();
//1
synchronized (options) {
setChannelOptions(channel, options, logger);
}
//2
final Map, Object> attrs = attrs0();
synchronized (attrs) {
for (Entry, Object> e: attrs.entrySet()) {
@SuppressWarnings("unchecked")
AttributeKey key = (AttributeKey) e.getKey();
channel.attr(key).set(e.getValue());
}
}
//3
ChannelPipeline p = channel.pipeline();
final EventLoopGroup currentChildGroup = childGroup;
final ChannelHandler currentChildHandler = childHandler;
final Entry, Object>[] currentChildOptions;
final Entry, Object>[] currentChildAttrs;
synchronized (childOptions) {
currentChildOptions = childOptions.entrySet().toArray(newOptionArray(childOptions.size()));
}
synchronized (childAttrs) {
currentChildAttrs = childAttrs.entrySet().toArray(newAttrArray(childAttrs.size()));
}
//4
p.addLast(new ChannelInitializer() {
@Override
public void initChannel(final Channel ch) throws Exception {
final ChannelPipeline pipeline = ch.pipeline();
ChannelHandler handler = config.handler();
if (handler != null) {
pipeline.addLast(handler);
}
ch.eventLoop().execute(new Runnable() {
@Override
public void run() {
pipeline.addLast(new ServerBootstrapAcceptor(
ch, currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs));
}
});
}
});
}
config().group().register(channel)
config().group()
是获取到线程池,该线程池是ServerBootstrap
的父类AbstractBootstrap
存储的boss线程池。是不是恍然大悟,这就是把channel放到boss线程池里的一个线程里面去执行任务啊。
1 是MultithreadEventLoopGroup
类的方法 也就是NioEventLoopGroup
的父类。 该方法就是从线程池里获取一个EventLoop.然后执行EventLoop里的register()方法。
@Override
public EventLoop next() {
return (EventLoop) super.next();
}
@Override
public ChannelFuture register(Channel channel) {
return next().register(channel); //1
}
继续看下去。
2 是SingleThreadEventLoop
里的方法。``DefaultChannelPromise()` 方法是给channel 与该线程 添加一个监听器。
@Override
public ChannelFuture register(Channel channel) {
//2
return register(new DefaultChannelPromise(channel, this));
}
继续往下看
3 继续是SingleThreadEventLoop
里的方法。promise是监听器对象,promise.channel()
获取到channel。unsafe()
方法是实现底层的register,read或者write操作
@Override
public ChannelFuture register(final ChannelPromise promise) {
//3
ObjectUtil.checkNotNull(promise, "promise");
promise.channel().unsafe().register(this, promise);
return promise;
}
继续往下分析,该register()方法是AbstractChannel
类的。也就是初始化NioServerSocketChannel
的时候,建立pipeline和unsafe的类。
4 进行参数验证
5 将该eventLoop线程赋值于channel参数。
6 eventLoop.inEventLoop() 判断,如果现在的线程是EventLoop()的 线程,那么执行任务,如果不是那么就用执行器执行任务。在这里debug,会返回false,会调用execute()方法。 下面继续探讨
7 下面探讨下register0()
方法
@Override
public final void register(EventLoop eventLoop, final ChannelPromise promise) {
//4
if (eventLoop == null) {
throw new NullPointerException("eventLoop");
}
if (isRegistered()) {
promise.setFailure(new IllegalStateException("registered to an event loop already"));
return;
}
if (!isCompatible(eventLoop)) {
promise.setFailure(
new IllegalStateException("incompatible event loop type: " + eventLoop.getClass().getName()));
return;
}
//5
AbstractChannel.this.eventLoop = eventLoop;
//6
if (eventLoop.inEventLoop()) {
register0(promise);
} else {
try {
eventLoop.execute(new Runnable() {
@Override
public void run() {
//7
register0(promise);
}
});
} catch (Throwable t) {
}
}
}
首先在研究register0()之前有一个小知识。
在版本4.1.x 的时候,在初始化eventLoop
的时候,还没有创建线程,而是保存了Executor
这个变量。这个变量在4.0.x版本的时候是没有的。那么4.1.x版本在什么时候创建线程呢?在eventLoop调用execute()方法的时候创建线程。下文可以看到
1 继续判断是否现在的线程是EventLoop对象的线程,肯定返回false,因为EventLoop线程里的thread变量是null
嘛。
@Override
public boolean inEventLoop(Thread thread) {
return thread == this.thread;
}
2 在startThread()
方法中,才创建一个线程。
3 在任务队列里添加一个任务。
public void execute(Runnable task) {
if (task == null) {
throw new NullPointerException("task");
}
//1
boolean inEventLoop = inEventLoop();
if (inEventLoop) {
addTask(task);
} else {
//2
startThread();
//3
addTask(task);
if (isShutdown() && removeTask(task)) {
reject();
}
}
if (!addTaskWakesUp && wakesUpForTask(task)) {
wakeup(inEventLoop);
}
}
register0(ChannelPromise promise)
1 判断EventLoop线程是否还存活。
2 这个是记录是否注册过的。neverRegistered
默认是true;
3 这个是核心代码
,到这里才进行将channel与selector注册在一起。
private void register0(ChannelPromise promise) {
try {
//1
if (!promise.setUncancellable() || !ensureOpen(promise)) {
return;
}
//2
boolean firstRegistration = neverRegistered;
doRegister();//3
neverRegistered = false;
registered = true;
pipeline.invokeHandlerAddedIfNeeded();
safeSetSuccess(promise);
pipeline.fireChannelRegistered();
if (isActive()) {
if (firstRegistration) {
pipeline.fireChannelActive();
} else if (config().isAutoRead()) {
beginRead();
}
}
} catch (Throwable t) {
}
}
你可能感兴趣的:(Netty源码分析:1.4服务器启动流程)
反向代理模块
xianwu543
c++ 开发语言 网络 mysql 数据库
1概念1.1反向代理概念反向代理是指以代理服务器来接收客户端的请求,然后将请求转发给内部网络上的服务器,将从服务器上得到的结果返回给客户端,此时代理服务器对外表现为一个反向代理服务器。对于客户端来说,反向代理就相当于目标服务器,只需要将反向代理当作目标服务器一样发送请求就可以了,并且客户端不需要进行任何设置。1.2特点反向代理是代理服务器,为服务器收发请求,使真实服务器对客户端不可见。原文链接:h
【CCM-SLAM论文阅读笔记】
随机取名字
协同SLAM论文阅读 slam
CCM-SLAM论文阅读笔记整体框架结构如图所示:单智能体只负责采集图像数据,运行实时视觉里程计VO以估计当前位姿和环境地图,由于单智能体计算资源有限,负责生成的局部地图只包含当前N个最近的关键帧。服务器负责地图管理、地点识别、地图融合和全局BA优化。所有局部地图使用本地里程计框架,地图信息在从一个本地里程计到另一个本地里程计框架的相对坐标中进行交换。CCM-SLAM不假设任何关于智能体初始位置的
Vite 学习笔记
a鲸
前端
优势vite是vue团队官方出品,vue-cli会在下面两个版本中将vite作为预设构建工具未来适用vue-cli构建vue项目时要写的vue.config.js不再是webpack的配置而是vite的配置(目前只基于浏览器项目)vite也支持构建react项目,也支持构建angular项目,svelte项目也支持构建内容1.什么是构建工具构建工具是运行在服务器的企业级项目里都可能会具备哪些功能t
【纯干货】SSM(Spring + SpringMVC + MyBatis)环境搭建
Chin_Yuu
mybatis spring java servlet
目录什么是SSM?SSM(Spring+SpringMVC+MyBatis)环境搭建1.导入依赖2.搭建Spring整合MyBatis环境MyBatis配置类根据业务测试环境的搭建3.加入SpringMVC配置类书写服务器和应用控制器测试SpringMVC的环境总结SSM框架的优点:什么是SSM?SSM框架,是Spring+SpringMVC+MyBatis的缩写,这个是继SSH之后,目前比较主流
SQL注入漏洞解析:如何利用LOAD_FILE()和SELECT INTO OUTFILE读取与写入服务器文件[webshell] 超详细文章
浩策
SQL注入漏洞 安全 web安全 网络安全 安全架构 密码学 可信计算技术
目录SQL读取文件漏洞特权数据库用户查询用户权限我们的UNION注入payload如下:用户权限代码:sql代码:sql代码:sql其它权限查询代码:sql代码:sql加载文件[LOAD_FILE()]sql读取漏洞代码:sql代码:sql另一个例子代码:sqlsql文件读取漏洞利用条件--------------------------------------------------------
关于服务器虚拟化不能不知道的几个重要知识点!
Stanford_1106
学习 服务器 微信开放平台 微信小程序 微信公众平台 twitter 运维
成长路上不孤单【14后///计算机爱好者///持续分享所学///如有需要欢迎收藏转发///】今日分享关于服务器虚拟化的相关内容!关于【服务器虚拟化】目录:一、服务器虚拟化的概念二、服务器虚拟化的技术实现途径三、服务器虚拟化的优势和特点四、服务器虚拟化的应用场景五、服务器虚拟化技术的主要类型一、服务器虚拟化的概念服务器虚拟化是一种将物理服务器资源转化为虚拟服务器资源的技术,它允许在一台物理服务
如何通过 Python 实现一个消息队列,为在线客服系统与海外运营的APP对接
我在业余时间开发了一款自己的独立产品:升讯威在线客服与营销系统。陆陆续续开发了几年,从一开始的偶有用户尝试,到如今线上环境和私有化部署均有了越来越多的稳定用户。而我收到的用户需求也越来越多,产品化的需求,个性化的需求都有。这段时间收到一个海外APP的对接需求,需要我将客服系统的消息以队列的形式转发到对方的业务服务器上。对方有两个核心需求:访客上线的时候,要通知对方的业务系统,业务系统根据访客的身份
图片加水印并推送邮箱
言慢行善
windows
实际情况:根据贺卡图片,依据工作时限是否满足周年纪念,填入对应员工姓名,将生成的图片以邮件形式推送该员工邮箱。准备工作:贺卡模型图片model.jpg[本地测试或上传到文件服务器测试]直接代码://每日同步符合周年纪念的人员publicvoiddailyAnniversaryOfUser(){//查询所有在职人员ListuserList=userService.getAllUserCond();/
内网穿透——windows系统中搭建私人影音平台
远程远程办公windows
在Windows系统中搭建私人影音平台并实现内网穿透,可以让用户随时随地远程访问自己的影音资源。以下是详细的步骤和说明:一、选择影音服务器软件首先,需要选择一款合适的影音服务器软件。常见的影音服务器软件有Emby、Plex和Jellyfin等。这些软件都支持多种操作系统,包括Windows,且拥有强大的功能和友好的用户界面。二、下载并安装影音服务器软件访问官网:打开Emby、Plex或Jellyf
MySQL主从同步必然有延迟,怎么解决 ?
冰糖心书房
2025 Java面试系列 Mysql mysql 数据库
MySQL主从同步延迟是生产环境中常见的问题,虽然无法完全消除延迟(受网络、硬件、负载等因素影响),但可以通过多种方法来缓解和解决延迟带来的问题。下面是一些常用的解决方案:1.优化硬件和网络:使用高性能硬件:更快的CPU、更大的内存、更快的磁盘(SSD)可以提高MySQL服务器的处理能力,减少同步延迟。优化网络:确保主从服务器之间的网络连接稳定、低延迟、高带宽。使用专线或高质量的网络连接。避免网络
BFS算法——层层推进,最短之路,广度优先搜索算法的诗意旅程(下)
诚丞成
常用算法讲解 算法 宽度优先
文章目录引言一.迷宫中离入口最近的出口1.1题目链接:https://leetcode.cn/problems/nearest-exit-from-entrance-in-maze/1.2题目分析:1.3思路讲解:1.4代码实现:二.最小基因变化2.1题目链接:https://leetcode.cn/problems/minimum-genetic-mutation/description/2.2
Linux操作系统:智能工业电表开发
暮雨哀尘
Linux的那点事 服务器 linux 微信 web开发 数据库 运维
智能工业电表开发文档(基于Linux操作系统)1.项目概述智能工业电表是一款用于实时监测工业设备电流和电压的系统。它通过嵌入式Linux设备采集数据,并将数据上传到云端服务器。用户可以通过微信小程序查询设备的实时数据和历史数据,并进行充值操作。2.系统架构2.1系统架构图+-------------------++------------------++-------------------+||
二、C语言分支循环语句
无他.唯手熟尔
c语言 开发语言
目录1、if语句1.1if语句的基本语法1.1.1单分支结构1.1.2双分支结构1.1.3多分支结构1.2if语句的核心规则1.2.1条件表达式1.2.2代码块与大括号1.2.3嵌套if语句1.3if语句的使用场景1.3.1数值范围判断1.3.2字符或枚举类型判断1.3.3逻辑组合判断1.4if语句的注意事项1.4.1常见错误1.4.2悬空else问题1.5if语句的优缺点1.6总结2、switc
MySQL-SQL
我是西瓜王
mysql sql 数据库
1.客户端内置命令客户端内置命令客户端独有,可能不同数据库产品的客户端内置命令存在很大差异,不像SQL命令有标准规范。help\h?\?这四个命令都可以输出帮助文档查看客户端内置命令?(\?)“帮助”的同义词。clear(\c)清除当前输入语句。connect(\r)重新连接到服务器。可选参数是db和host。delimiter(\d)设置语句分隔符,默认是;。edit(\e)使用$EDITOR执
7天撸完KTV点歌系统,含后台管理系统(完整版)
码上来財
Node Vue Node Vue Mongodb ElementUI Express
最近手有点痒琢磨着做个啥,朝思暮想还是写个KTV点歌系统,模拟了一下KTV开户的思路,7天累死我了,不过技术点还挺多的,希望你可以看完(〜㉨)〜用Node(Express)教你写KTV点歌系统,包括前台内容和后台管理系统,整合Express框架和Mongodb数据库服务器开发;教你用Vue.JS,ElementUI和iViewUI写出超漂亮的页面,随心点歌随心听思维导图技术栈后端:Express+
【原创】谈谈redis的热key问题如何解决
qdwd888
Java 经验分享 面试 java
ps:hotkey和bigkey问题,大家一定要有所了解。本文预计分为如下几个部分热key问题如何发现业内方案正文–热Key问题上面提到,所谓热key问题就是,突然有几十万的请求去访问redis上的某个特定key。那么,这样会造成流量过于集中,达到物理网卡上限,从而导致这台redis的服务器宕机。那接下来这个key的请求,就会直接怼到你的数据库上,导致你的服务不可用。怎么发现热key方法一:凭借业
openwrt 自定义DHCP
伊一线天
DHCP是广播服务,除非通过VLAN定义作用域,否则无法指定多个DHCP服务器对不同的客户端提供服务。家用DHCP自定义服务功能(指定单独的网关、DNS服务器)使用Dnsmasq服务来增强。在openwrt里Dnsmasq的配置文件也在/etc/config/dhcp文件思路是,给静态DHCP服务,给需要不同配置的的Host打上TAG,相同TAG的主机单独配置dhcp_option具体如下。con
相比于WebSocket,SSE更适合轻量级
沐雨MUYU_
websocket 网络协议 前端
一、前言项目首页有一个待办任务数量和消息提醒数量的展示(单向数据的展示),之前使用了定时器,每隔十秒钟发送一次请求到后端接口拿数据,这也就是我们常说的轮询做法。1.轮询的缺点我们都知道轮询的缺点有几种:资源浪费:网络带宽:频繁的请求可能导致不必要的网络流量,增加带宽消耗。服务器负载:每次请求都需要服务器处理,即使是空返回,也会增加服务器的CPU和内存负载。用户体验:界面卡顿:频繁的请求和更新可能会
常见网络攻击以及防御方法大全,零基础入门到精通,收藏这一篇就够了
网安导师小李
程序员 编程 网络安全 网络 web安全 前端 运维 安全 python java
网络安全威胁类别网络内部的威胁,网络的滥用,没有安全意识的员工,黑客,骇客。木马攻击原理C/S架构,服务器端被植入目标主机,服务器端通过反弹连接和客户端连接。从而客户端对其进行控制。病毒一些恶意的计算机程序,具有传播性,破坏性,隐蔽性的特点。网络攻击类型主要分为三类:**侦查攻击:**搜集网络存在的弱点,以进一步攻击网络。分为扫描攻击和网络监听:扫描攻击有端口扫描,主机扫描,漏洞扫描。**网络监听
HUSTOJ随笔4-建立分布式判题系统
歪嘴鱼
hustoj 数据库服务器 数据库 远程连接 虚拟机 web服务
HUSTOJ支持一台数据库服务器,多台web服务器和多台判题服务器,以承担较高的访问负荷。首先,需要创建用于从远程连接数据库的帐号。GRANTALLPRIVILEGESONjol.*TO'judge'@'%'IDENTIFIEDBY'judge_pass'WITHOUTGRANTOPTION;flushprivileges复制代码其中jol为数据库,judge为帐号,judge_pass为密码。注
如何使用 Java 读取本地文件并转换为 MultipartFile 对象
火皇405
java 开发语言 tomcat spring spring boot
在许多JavaWeb应用中,我们经常会遇到将本地文件上传至服务器或其他系统的需求。在这种场景下,MultipartFile对象非常常用,用来表示HTTP请求中的文件。在本文中,我将演示如何编写代码来读取本地文件并将其转换为自定义的MultipartFile对象。1.基本需求为了将本地文件读取并转换为MultipartFile,我们需要完成以下任务:读取文件的内容和类型。构建MultipartFil
tftp服务器上传文件至华三ac,ftp和tftp 上传文件到h3c交换机
刘虓震
一、ftp(1)交换机配置:在交换机上添加一个本地用户abc,并设置其认证密码为123456,访问时使用的用户角色为network-admin,授权访问目录为全局主用主控板Flash的根目录,abc可以使用的服务类型为FTP。system-view[Sysname]local-userabcclassmanage[Sysname-luser-abc]passwordsimple123456[Sys
【工具篇】DeepSeek服务繁忙,可以试一下这个新途径
再见孙悟空_
【2025 AI学习从零单排系列 】 【2025AI工具合集】 超算互联网 DeepSeek服务繁忙 DeepSeek DeepSeek访问受限
最近,我发现许多用户都在抱怨DeepSeek访问不了,服务器好像“炸了”。这让我想起了一个更严重的问题:当AI服务的大脑——serversoverwhelmed,整个系统就无法运转。那么,如何应对这种serveroverload的危机?答案就在眼前——超算互联网来了!一、服务器压力,whyit'shappeningDeepSeek这样的AI服务,背后需要massivecomputationalpo
/usr/share/nginx/html 目录到底是干什么的?
快点好好学习吧
PHP nginx html java
/usr/share/nginx/html目录是干什么的?想象一下,你有一个展示柜,专门用来摆放你的宝贝,比如玩具、照片或收藏品。每当有客人来家里时,他们首先会看到这个展示柜里的东西。在Nginx(一个非常流行的网页服务器软件)的世界里,/usr/share/nginx/html就像是这样一个展示柜。/usr/share/nginx/html是什么?Nginx的默认网页目录:当有人通过互联网访问你
H3C和华为产品定期将配置文件保存到FTP服务器的配置步骤
normanhere
服务器 华为 网络
H3C产品配置:sysschedulerjobsaveconfigcommand1saveforcecommand2copystartup.cfgftp://username:password@1.1.1.1/filenamequitschedulerschedulesaveconfigjobsaveconfigtimerepeatingat14:30week-daySatquitsaveforc
解决DeepSeek服务器繁忙问题
大富大贵7
程序员知识储备1 经验分享
针对DeepSeek服务器繁忙问题,以下是分步解决方案:---**1.诊断问题根源**-**监控资源使用率**:通过工具(如`top`,`htop`,`vmstat`)实时检查CPU、内存、磁盘I/O和网络带宽占用情况。-**分析日志**:查看Web服务器(Nginx/Apache)和应用程序日志,定位响应延迟的请求或错误频发点。-**数据库性能**:检查慢查询日志(如MySQL的`slow_qu
使用`nohup`后台运行Python服务不输出日志避坑
LensonYuan
Python工程落地 python 开发语言
解决使用nohup后台运行Python服务不输出日志的问题在服务器环境中,我们经常需要将Python程序设置为后台运行,以便它们可以在系统重启后继续运行。nohup是Linux系统中的一个实用工具,用于在用户退出终端后仍继续运行进程。然而,有时你会发现日志没有正确地被记录。本文将介绍一些常见的问题及相应的解决方法。后台运行Python程序的方法直接在当前目录生成日志文件nohuppythonyou
高防服务器和普通服务器有什么区别?
wanhengidc
服务器 运维
高防服务器是一种具备高防御能力的服务器,主要是用来抵御各种网络攻击,可以保护网站或者是应用的安全和稳定运行,具有着强大的防御能力和安全保护措施,能够承受更高强度的网络攻击;普通服务器则是用来存储和处理数据以及提供服务,没有特别的安全保护措施,有着最为基本的防火墙和网络安全机制。相比较来说,高防服务器比普通服务器有着更安全的保障,有着较为完善的安全措施,可以有效抵御各种网络攻击,让恶意攻击者无法轻松
使用docker部署NextChat,使用阿里云、硅机流动、deepseek的apikey
喝水塞牙
docker 阿里云 容器
1、首先使用安装好了docker的服务器拉取NextChat项目[root@xxdocker]#dockerpullyidadaa/chatgpt-next-web2、启动docker容器,基于不同平台以下的OPENAI_API_KEY参数替换成自己的就行,启动后访问地址:http://[服务器ip]:3000/#硅机流动[root@xxdocker]#dockerrun--namenextcha
阿里云 ACS:高效、弹性、低成本的容器计算解决方案
Anna_Tong
阿里云 云计算 人工智能 devops 容器 serverless kubernetes
阿里云的容器计算服务(AlibabaCloudContainerService,ACS)是一种Serverless容器计算解决方案,提供高度弹性、低成本、易管理的Kubernetes(K8s)容器运行环境。用户无需关注底层服务器资源,而是直接管理容器工作负载,从而提升运维效率和资源利用率。1.主要应用场景ACS适用于多种业务类型,尤其是在弹性计算和微服务架构领域,具有独特优势。(1)在线业务和We
Java序列化进阶篇
g21121
java序列化
1.transient
类一旦实现了Serializable 接口即被声明为可序列化,然而某些情况下并不是所有的属性都需要序列化,想要人为的去阻止这些属性被序列化,就需要用到transient 关键字。
escape()、encodeURI()、encodeURIComponent()区别详解
aigo
JavaScript Web
原文:http://blog.sina.com.cn/s/blog_4586764e0101khi0.html
JavaScript中有三个可以对字符串编码的函数,分别是: escape,encodeURI,encodeURIComponent,相应3个解码函数:,decodeURI,decodeURIComponent 。
下面简单介绍一下它们的区别
1 escape()函
ArcgisEngine实现对地图的放大、缩小和平移
Cb123456
添加矢量数据 对地图的放大、缩小和平移 Engine
ArcgisEngine实现对地图的放大、缩小和平移:
个人觉得是平移,不过网上的都是漫游,通俗的说就是把一个地图对象从一边拉到另一边而已。就看人说话吧.
具体实现:
一、引入命名空间
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Controls;
二、代码实现.
Java集合框架概述
天子之骄
Java集合框架概述
集合框架
集合框架可以理解为一个容器,该容器主要指映射(map)、集合(set)、数组(array)和列表(list)等抽象数据结构。
从本质上来说,Java集合框架的主要组成是用来操作对象的接口。不同接口描述不同的数据类型。
简单介绍:
Collection接口是最基本的接口,它定义了List和Set,List又定义了LinkLi
旗正4.0页面跳转传值问题
何必如此
java jsp
跳转和成功提示
a) 成功字段非空forward
成功字段非空forward,不会弹出成功字段,为jsp转发,页面能超链接传值,传输变量时需要拼接。接拼接方式list.jsp?test="+strweightUnit+"或list.jsp?test="+weightUnit+&qu
全网唯一:移动互联网服务器端开发课程
cocos2d-x小菜
web开发 移动开发 移动端开发 移动互联 程序员
移动互联网时代来了! App市场爆发式增长为Web开发程序员带来新一轮机遇,近两年新增创业者,几乎全部选择了移动互联网项目!传统互联网企业中超过98%的门户网站已经或者正在从单一的网站入口转向PC、手机、Pad、智能电视等多端全平台兼容体系。据统计,AppStore中超过85%的App项目都选择了PHP作为后端程
Log4J通用配置|注意问题 笔记
7454103
DAO apache tomcat log4j Web
关于日志的等级 那些去 百度就知道了!
这几天 要搭个新框架 配置了 日志 记下来 !做个备忘!
#这里定义能显示到的最低级别,若定义到INFO级别,则看不到DEBUG级别的信息了~!
log4j.rootLogger=INFO,allLog
# DAO层 log记录到dao.log 控制台 和 总日志文件
log4j.logger.DAO=INFO,dao,C
SQLServer TCP/IP 连接失败问题 ---SQL Server Configuration Manager
darkranger
sql c windows SQL Server XP
当你安装完之后,连接数据库的时候可能会发现你的TCP/IP 没有启动..
发现需要启动客户端协议 : TCP/IP
需要打开 SQL Server Configuration Manager...
却发现无法打开 SQL Server Configuration Manager..??
解决方法: C:\WINDOWS\system32目录搜索framedyn.
[置顶] 做有中国特色的程序员
aijuans
程序员
从出版业说起 网络作品排到靠前的,都不会太难看,一般人不爱看某部作品也是因为不喜欢这个类型,而此人也不会全不喜欢这些网络作品。究其原因,是因为网络作品都是让人先白看的,看的好了才出了头。而纸质作品就不一定了,排行榜靠前的,有好作品,也有垃圾。 许多大牛都是写了博客,后来出了书。这些书也都不次,可能有人让为不好,是因为技术书不像小说,小说在读故事,技术书是在学知识或温习知识,有些技术书读得可
document.domain 跨域问题
avords
document
document.domain用来得到当前网页的域名。比如在地址栏里输入:javascript:alert(document.domain); //www.315ta.com我们也可以给document.domain属性赋值,不过是有限制的,你只能赋成当前的域名或者基础域名。比如:javascript:alert(document.domain = "315ta.com");
关于管理软件的一些思考
houxinyou
管理
工作好多看年了,一直在做管理软件,不知道是我最开始做的时候产生了一些惯性的思维,还是现在接触的管理软件水平有所下降.换过好多年公司,越来越感觉现在的管理软件做的越来越乱.
在我看来,管理软件不论是以前的结构化编程,还是现在的面向对象编程,不管是CS模式,还是BS模式.模块的划分是很重要的.当然,模块的划分有很多种方式.我只是以我自己的划分方式来说一下.
做为管理软件,就像现在讲究MVC这
NoSQL数据库之Redis数据库管理(String类型和hash类型)
bijian1013
redis 数据库 NoSQL
一.Redis的数据类型
1.String类型及操作
String是最简单的类型,一个key对应一个value,string类型是二进制安全的。Redis的string可以包含任何数据,比如jpg图片或者序列化的对象。
Set方法:设置key对应的值为string类型的value
Tomcat 一些技巧
征客丶
java tomcat dos
以下操作都是在windows 环境下
一、Tomcat 启动时配置 JAVA_HOME
在 tomcat 安装目录,bin 文件夹下的 catalina.bat 或 setclasspath.bat 中添加
set JAVA_HOME=JAVA 安装目录
set JRE_HOME=JAVA 安装目录/jre
即可;
二、查看Tomcat 版本
在 tomcat 安装目
【Spark七十二】Spark的日志配置
bit1129
spark
在测试Spark Streaming时,大量的日志显示到控制台,影响了Spark Streaming程序代码的输出结果的查看(代码中通过println将输出打印到控制台上),可以通过修改Spark的日志配置的方式,不让Spark Streaming把它的日志显示在console
在Spark的conf目录下,把log4j.properties.template修改为log4j.p
Haskell版冒泡排序
bookjovi
冒泡排序 haskell
面试的时候问的比较多的算法题要么是binary search,要么是冒泡排序,真的不想用写C写冒泡排序了,贴上个Haskell版的,思维简单,代码简单,下次谁要是再要我用C写冒泡排序,直接上个haskell版的,让他自己去理解吧。
sort [] = []
sort [x] = [x]
sort (x:x1:xs)
| x>x1 = x1:so
java 路径 配置文件读取
bro_feng
java
这几天做一个项目,关于路径做如下笔记,有需要供参考。
取工程内的文件,一般都要用相对路径,这个自然不用多说。
在src统计目录建配置文件目录res,在res中放入配置文件。
读取文件使用方式:
1. MyTest.class.getResourceAsStream("/res/xx.properties")
2. properties.load(MyTest.
读《研磨设计模式》-代码笔记-简单工厂模式
bylijinnan
java 设计模式
声明: 本文只为方便我个人查阅和理解,详细的分析以及源代码请移步 原作者的博客http://chjavach.iteye.com/
package design.pattern;
/*
* 个人理解:简单工厂模式就是IOC;
* 客户端要用到某一对象,本来是由客户创建的,现在改成由工厂创建,客户直接取就好了
*/
interface IProduct {
SVN与JIRA的关联
chenyu19891124
SVN
SVN与JIRA的关联一直都没能装成功,今天凝聚心思花了一天时间整合好了。下面是自己整理的步骤:
一、搭建好SVN环境,尤其是要把SVN的服务注册成系统服务
二、装好JIRA,自己用是jira-4.3.4破解版
三、下载SVN与JIRA的插件并解压,然后拷贝插件包下lib包里的三个jar,放到Atlassian\JIRA 4.3.4\atlassian-jira\WEB-INF\lib下,再
JWFDv0.96 最新设计思路
comsci
数据结构 算法 工作 企业应用 公告
随着工作流技术的发展,工作流产品的应用范围也不断的在扩展,开始进入了像金融行业(我已经看到国有四大商业银行的工作流产品招标公告了),实时生产控制和其它比较重要的工程领域,而
vi 保存复制内容格式粘贴
daizj
vi 粘贴 复制 保存原格式 不变形
vi是linux中非常好用的文本编辑工具,功能强大无比,但对于复制带有缩进格式的内容时,粘贴的时候内容错位很严重,不会按照复制时的格式排版,vi能不能在粘贴时,按复制进的格式进行粘贴呢? 答案是肯定的,vi有一个很强大的命令可以实现此功能 。
在命令模式输入:set paste,则进入paste模式,这样再进行粘贴时
shell脚本运行时报错误:/bin/bash^M: bad interpreter 的解决办法
dongwei_6688
shell脚本
出现原因:windows上写的脚本,直接拷贝到linux系统上运行由于格式不兼容导致
解决办法:
1. 比如文件名为myshell.sh,vim myshell.sh
2. 执行vim中的命令 : set ff?查看文件格式,如果显示fileformat=dos,证明文件格式有问题
3. 执行vim中的命令 :set fileformat=unix 将文件格式改过来就可以了,然后:w
高一上学期难记忆单词
dcj3sjt126com
word english
honest 诚实的;正直的
argue 争论
classical 古典的
hammer 锤子
share 分享;共有
sorrow 悲哀;悲痛
adventure 冒险
error 错误;差错
closet 壁橱;储藏室
pronounce 发音;宣告
repeat 重做;重复
majority 大多数;大半
native 本国的,本地的,本国
hibernate查询返回DTO对象,DTO封装了多个pojo对象的属性
frankco
POJO hibernate查询 DTO
DTO-数据传输对象;pojo-最纯粹的java对象与数据库中的表一一对应。
简单讲:DTO起到业务数据的传递作用,pojo则与持久层数据库打交道。
有时候我们需要查询返回DTO对象,因为DTO
Partition List
hcx2013
partition
Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x.
You should preserve the original relative order of th
Spring MVC测试框架详解——客户端测试
jinnianshilongnian
上一篇《Spring MVC测试框架详解——服务端测试》已经介绍了服务端测试,接下来再看看如果测试Rest客户端,对于客户端测试以前经常使用的方法是启动一个内嵌的jetty/tomcat容器,然后发送真实的请求到相应的控制器;这种方式的缺点就是速度慢;自Spring 3.2开始提供了对RestTemplate的模拟服务器测试方式,也就是说使用RestTemplate测试时无须启动服务器,而是模拟一
关于推荐个人观点
liyonghui160com
推荐系统 关于推荐个人观点
回想起来,我也做推荐了3年多了,最近公司做了调整招聘了很多算法工程师,以为需要多么高大上的算法才能搭建起来的,从实践中走过来,我只想说【不是这样的】
第一次接触推荐系统是在四年前入职的时候,那时候,机器学习和大数据都是没有的概念,什么大数据处理开源软件根本不存在,我们用多台计算机web程序记录用户行为,用.net的w
不间断旋转的动画
pangyulei
动画
CABasicAnimation* rotationAnimation;
rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
rotationAnimation.toValue = [NSNumber numberWithFloat: M
自定义annotation
sha1064616837
java enum annotation reflect
对象有的属性在页面上可编辑,有的属性在页面只可读,以前都是我们在页面上写死的,时间一久有时候会混乱,此处通过自定义annotation在类属性中定义。越来越发现Java的Annotation真心很强大,可以帮我们省去很多代码,让代码看上去简洁。
下面这个例子 主要用到了
1.自定义annotation:@interface,以及几个配合着自定义注解使用的几个注解
2.简单的反射
3.枚举
Spring 源码
up2pu
spring
1.Spring源代码
https://github.com/SpringSource/spring-framework/branches/3.2.x
注:兼容svn检出
2.运行脚本
import-into-eclipse.bat
注:需要设置JAVA_HOME为jdk 1.7
build.gradle
compileJava {
sourceCompatibilit
利用word分词来计算文本相似度
yangshangchuan
word word分词 文本相似度 余弦相似度 简单共有词
word分词提供了多种文本相似度计算方式:
方式一:余弦相似度,通过计算两个向量的夹角余弦值来评估他们的相似度
实现类:org.apdplat.word.analysis.CosineTextSimilarity
用法如下:
String text1 = "我爱购物";
String text2 = "我爱读书";
String text3 =