当前位置: 首页 > news >正文

做平台还是自己做网站小语种网站怎么做

做平台还是自己做网站,小语种网站怎么做,网站建设工具的公司,app界面设计网站目录 第一章 概念引入 1.分布式概念引入 第二章 Netty基础 - NIO 1.引言 1.1 什么是Netty#xff1f; 1.2 为什么要学习Netty#xff1f; 2.NIO编程 2.1 传统网络通信中开发方式及问题#xff08;BIO#xff09; 2.1.1 多线程版网络编程 2.1.2 线程池版的网络编程…目录 第一章 概念引入 1.分布式概念引入 第二章 Netty基础 - NIO 1.引言 1.1 什么是Netty 1.2 为什么要学习Netty 2.NIO编程 2.1 传统网络通信中开发方式及问题BIO 2.1.1 多线程版网络编程 2.1.2 线程池版的网络编程 2.2 NIO网络通信中的非阻塞编程 3.NIO的基本开发方式 3.1 Channel简介 3.2 Buffer简介 3.3 第一个NIO程序 3.5 NIO步骤总结 第一章 概念引入 1.分布式概念引入 很多年前的开发其实就是单机开发但现如今随着流量并发的增加引入了分布式。 对于后端而言分布式专注于服务器端。当client客户端过多时我们在服务端要考虑很多问题首先第一个就是并发问题如何支持并发 先说一个旧时代方案做水平扩展扩展成n多台tomcat服务器并且做负载均衡但是这仅仅是在硬件层面上去做扩展。 新时代方案构建分布式系统也就是使用一系列分布式技术方案进行构建系统不仅在硬件机器层面去做扩展而且要在软件层面做扩展。有以下几点需要注意 1如何进行服务的管理 目前的解决方案为SpringCloud。但是SpringCloud开发有很多弊端1.代码侵入性太强 ---分析需要打注解做注解的过程实际上就是代码侵入的过程。并且当我们需要更改通信模块所使用到的技术时当前代码基本上废了。2.只支持java语言做开发gopy不支持。 所以新时代分布式构建时会慢慢的向ServerMash网格化开发靠近把每一项功能做成一个中间件降低侵入性和语言局限性 2如何进行通信管理 Netty 3如何进行资源管理 这一部分比较偏向硬件管理了像如今的k8sdocker容器化管理资源 第二章 Netty基础 - NIO 1.引言 1.1 什么是Netty Netty: Home Netty is an asynchronous event-driven network application frameworkfor rapid development of maintainable high performance protocol servers clients. Netty是一个异步事件驱动的网络应用框架。用于快速开发可维护的高性能协议服务器和客户端。 Netty is a NIO client server framework which enables quick and easy development of network applications such as protocol servers and clients. It greatly simplifies and streamlines network programming such as TCP and UDP socket server. Quick and easy doesnt mean that a resulting application will suffer from a maintainability or a performance issue. Netty has been designed carefully with the experiences earned from the implementation of a lot of protocols such as FTP, SMTP, HTTP, and various binary and text-based legacy protocols. As a result, Netty has succeeded to find a way to achieve ease of development, performance, stability, and flexibility without a compromise. Netty是一个NIO客户服务器框架它能够快速和容易地开发网络应用如协议服务器和客户端。它大大简化和精简了网络编程如TCP和UDP套接字服务器。 快速和简单 并不意味着开发出来的应用程序会出现可维护性或性能问题。Netty的设计是经过精心设计的其经验来自于许多协议的实施如FTP、SMTP、HTTP以及各种基于二进制和文本的遗留协议。因此Netty成功地找到了一种方法来实现开发的简易性、性能、稳定性和灵活性而没有任何妥协。 1.2 为什么要学习Netty 1. Netty已经是行业内网络通信编程的标准广泛应用于通信领域和很多其他中间件技术的底层。 2. 应用非常广泛 1. 游戏行业 ---》在很多中小型企业策略游戏的后端都是使用java来写的使用到java自然用Netty做网络通信。因为游戏对于消息协议的设计是高度定制化以及高要求化的 2. 很多框架的通信底层解决进程间通信。 Spring WebFlux、storm、rocketMQ、dubbo等是分布式系统通信的核心。 -----》对于新兴的WebFlux就是使用Netty作为网络通信框架基础包括大数据框架storm还有一些中间件产品分布式场景下多节点集群间需要通信Netty就是Java领域最优的解决方案。 2.NIO编程 1. NIO全称成为None Blocking IO (非阻塞IO)。【JDK1.4引入的一个java自带包】----》多说一句NIO为非阻塞同步IO虽然是非阻塞但依旧是同步的。 2. 非阻塞 主要应用在网络通信中能够合理利用资源提高系统的并发效率。支持高并发的系统访问。 ----》但是一定注意一点使用非阻塞网络通信只是提高系统并发的一个环节对于高并发产品有更多环节需要去考虑 2.1 传统网络通信中开发方式及问题BIO 2.1.1 多线程版网络编程 先看代码 public class MessiServer {public static void main(String[] args) {ServerSocket serverSocket null ;try {serverSocket new ServerSocket(8080) ;Socket socket null ;while(true) {socket serverSocket.accept() ;//服务器每监听到一个新客户端请求建立连接后开启一个新线程去执行处理对应的请求//start()---run()new Thread(new MessiServerHandler(socket)).start();}} catch (IOException e) {throw new RuntimeException(e);} finally {if(serverSocket ! null) {try {serverSocket.close();} catch (IOException e) {throw new RuntimeException(e);}}}}} class MessiServerHandler implements Runnable{private Socket socket ;public MessiServerHandler(Socket socket) {this.socket socket ;}public void run() {BufferedReader bufferedReader null ;try {bufferedReader new BufferedReader(new InputStreamReader(this.socket.getInputStream())) ;while(true) {String line bufferedReader.readLine() ;if(line ! null) {System.out.println(line line);}}} catch (IOException e) {throw new RuntimeException(e);} finally {if(bufferedReader ! null) {try {bufferedReader.close();} catch (IOException e) {throw new RuntimeException(e);}}}} } public class MessiClient {public static void main(String[] args) {Socket socket null ;PrintWriter printWriter null ;try {socket new Socket(localhost,8080) ;//editor-fold descIO流读写数据printWriter new PrintWriter(socket.getOutputStream());printWriter.write(send date to server );printWriter.flush();///editor-fold} catch (UnknownHostException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);} finally {//editor-fold desc关闭Socket资源if (socket ! null) {try {socket.close();} catch (IOException e) {throw new RuntimeException(e);}}if (printWriter ! null) {printWriter.close();}///editor-fold}}} 画图概括代码 补充1 JavaEE为我们封装了很多比如说透明化socket透明化Thread线程其实都是tomcat服务器为我们做了当然Tomcat做的很好比如说使用线程池来优化等等。 补充2 在如今BS交互层面一次浏览器客户端请求对应一个新连接先三次握手建立连接服务器端会创建一个新线程去处理这个请求连接当这个请求处理结束后这次请求所对应的客户端socket就会close掉其实我们通信说白了就是socket通信主要是看socket。所以可以说成一次请求对应一个线程。 分析缺点 1.线程创建开销大 分析 线程的创建是操作系统去创建的在jvm层面是无法去创建的。在系统层面我们一定会陷入内核态去调用操作系统提供的函数创建线程通知到操作系统操作系统与硬件做交互真正的分配一块内存空间去给线程这样开销一定是要比直接在jvm用户程序层面的开销大。 2.内存占用高不能无限制创建线程 分析 服务器端监听客户端的连接建立当有一个新客户端过来建立连接时就会开启一个新线程去处理这次建立连接后的请求假设说有100万个请求那么需要进行100万次客户端请求连接那么服务器端需要建立100万个线程去处理内存占用太高了。 eg假设说有1024个客户端进行连接服务器那么服务器对应就会有1024个线程进行创建并执行对应客户端的任务一个线程占用的空间大小为1MB那么1024个线程一共会占用1GB大小的空间假设说有1万个线程呢需要创建的内存空间是极大的占用内存是非常高 3.CPU使用率高 分析 虽说现在是多核CPU也就是一个CPU多核心这样可以很好的让多线程并行但是核心数也是有上限的我的电脑好像是八核也就是说可以8个线程并行操作。一旦开启线程数量超过8个那么就会并发执行所谓并发就是CPU不断上下文切换调度到底使用哪一个线程一旦涉及到上下文切换一定是高消耗的。我们需要不断的保存和恢复每个线程的上下文数据内容就算是内存级别的操作这也是很大的开销甚至有的上下文数据需要保存到磁盘做持久化这样消耗更大。一句话CPU需要不断的上下文切换调度CPU使用率一定高 2.1.2 线程池版的网络编程 先看代码 public class MessiServer1 {private static ExecutorService executorService;static {executorService new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(), 20,120L, TimeUnit.SECONDS, new ArrayBlockingQueueRunnable(1000));}public static void main(String[] args) {ServerSocket serverSocket null;try {serverSocket new ServerSocket(8080);Socket socket null;while (true) {socket serverSocket.accept();//new Thread(new SunsServerHandler(socket)).start();//线程池executorService.execute(new MessiServerHandler1(socket));}} catch (Exception e) {e.printStackTrace();} finally {if (serverSocket ! null) {try {serverSocket.close();} catch (IOException e) {throw new RuntimeException(e);}}}} } class MessiServerHandler1 implements Runnable {private Socket socket;public MessiServerHandler1(Socket socket) {this.socket socket;}public void run() {BufferedReader bufferedReader null;try {bufferedReader new BufferedReader(new InputStreamReader(this.socket.getInputStream()));while (true) {String line bufferedReader.readLine();if (line ! null) {System.out.println(line line);}}} catch (IOException e) {throw new RuntimeException(e);} finally {if (bufferedReader ! null) {try {bufferedReader.close();} catch (IOException e) {throw new RuntimeException(e);}}}} } public class MessiClient1 {public static void main(String[] args) {Socket socket null ;PrintWriter printWriter null ;try {socket new Socket(localhost,8080) ;//editor-fold descIO流读写数据printWriter new PrintWriter(socket.getOutputStream());printWriter.write(send date to server );printWriter.flush();///editor-fold} catch (UnknownHostException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);} finally {//editor-fold desc关闭Socket资源if (socket ! null) {try {socket.close();} catch (IOException e) {throw new RuntimeException(e);}}if (printWriter ! null) {printWriter.close();}///editor-fold}}} 代码细节分析 executorService new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(), 20, 120L, TimeUnit.SECONDS, new ArrayBlockingQueueRunnable(1000)); 参数1Runtime.getRuntime().availableProcessors() 为线程池的核心线程数量设置 ---》。API结果分情况讨论1.jdk8以及之前的版本该API获取到的是CPU所对应的核心数 2.jdk8以后该值的结果可以通过JVM参数进行自定义设置 为什么因为现如今都是docker虚拟容器化理论上是CPU有8个核但实际上docker虚拟化后只有4个核5个核都是有可能的 参数220 为线程池创建最大线程数 ----》参数1的结果值传入进去表示线程池申请的核心线程数量但是当client客户端连接变多时核心线程不够用了所以线程池会新创建线程(当然这个创建过程需要陷入内核然后OS......)但是创建的线程上限大小为20个 参数5 ----》当创建的线程数量达到最大线程数20个时还不够用那么把该线程对象(Tomcat会封装每一个请求成为一个个线程对象进入操作)加入到阻塞队列中但是阻塞队列上限为1000也就是说最多存储1000个阻塞线程对象超过则通过一些策略淘汰掉。 参数3参数4 当前线程超过120s没有执行任务会被回收销毁直到线程数量减少到Runtime.getRuntime().availableProcessors()这一设置的核心线程数量为止这样可以减少内存压力 画图概括代码 分析它解决的问题以及缺点 解决的问题 1.解决线程创建开销大的问题 分析通过线程池做管理解决这一问题 2.解决内存占用高无限创建线程问题 分析线程池做管理细节见上 3.解决CPU使用率高的问题 分析线程数有上限CPU切换调度不会很频繁 出现的新问题缺点 ServerSocket只能负责监听客户端的连接建立连接后创建开启一个新线程把当前连接所对应的客户端请求交给一个线程去做但是当这次请求过程中发生了一些阻塞如IO阻塞或等待客户键盘输入阻塞的话由于ServerSocket不能去管控这一阻塞ServerSocket只能负责监听客户端的连接所以当前请求所对应的Thread线程会一直阻塞着等待着这个阻塞所以会造成有限线程资源数的浪费。我们知道线程池中创建的线程是有限的资源如果有限的线程资源被阻塞式的任务请求占用着而那些迫切需要线程去处理的请求任务只能加入到阻塞队列中去等待甚至被拒绝这就是缺点极大的降低了并发 这一阻塞缺点就会引出后续的NIO 2.2 NIO网络通信中的非阻塞编程 网络IO所对应的NIO编程 针对于网络IO我们引入了Selector组件记住一定是针对于网络IO引入的Selector 常说的IO有文件IO和网络IO。在网络IO方面我们引入了一个组件Selector。该组件实现了监控管理客户端的作用具体流程如下在NIO编程过程中使用的是Channel管道代替传统的IO流会把不同客户端对应的Channel注册到Selector组件上Seletor进行监控注册在上面的所有客户端是否是正常的啥是正常正常就是能够在建立连接后正常的进行读写操作而不阻塞实现Selector监控后每一个Channel建立连接进行读写操作都会对应分配一个线程去执行。如果当Selector监控到某一分配了线程资源的Channel阻塞了那么Selector会把该线程资源归还回线程池而避免有限的线程资源被阻塞浪费当Channel正常后如果线程资源够用那么Selector会再一次给其分配线程资源 我们可以看出同一个线程资源被多个Channel复用这就是Select监控的作用这就是IO多路复用模型。对于Selector组件不同的操作系统实现不同有pollselectepoll。当然最好的就是epoll支持高并发 高可用所以我们经常把代码部署在Linux服务器上Linux服务器作为linux操作系统的计算机Selector的底层实现为epoll 文件IO所对应的NIO编程也是同理的 3.NIO的基本开发方式 3.1 Channel简介 1.Channel是IO通信的通道类似于InputStreamOutputStream 2.Channel没有方向性 传统IO NIO Channel在NIO中只起到一个管道传输数据的作用无方向 常见Channel 1. 文件操作 FileChannel读写文件中的数据。 2. 网络操作 SocketChannel通过TCP读写网络中的数据。 ServerSockectChannel监听新进来的TCP连接像Web服务器那样。对每一个新进来的连接都会创建一个SocketChannel。 DatagramChannel通过UDP读写网络中的数据。 获取Channel的方式 第一类如何获取文件IO所对应的Channel 1. FileInputStreanm/FileOutputStream 2. RandomAccessFile 第二类如何获取网络IO所对应的Channel 3. Socket 4. ServerSocket 5. DatagramSocket 3.2 Buffer简介 1. Channel读取或者写入的数据都要写到Buffer中才可以被程序操作。 2. 因为Channel没有方向性所以Buffer为了区分读写引入了读模式、写模式进行区分。 3.为什么要Buffer肯定是为了提升读写的效率缓冲区的作用就在于此。积攒到一定数据量后再一起读写比过来一个字节就进行读写要效率高 如图 NIO引入了Channel但是Channel是无方向的这不同于IO流的方向区分。 NIO是在Buffer上面做区分的给Buffer标记不同的状态进行区分到底是读出还是写入当Buffer缓冲区标记为写模式时表示写入数据到Buffer缓冲区下一步要进行的是把Buffer缓冲区的数据写入到文件中。当Buffer缓冲区标记为读模式时表示读出Buffer缓冲区的数据下一步要进行的是把Buffer缓冲区的数据读出到JVM程序中。 写模式何时开启当新创建一个Buffer时默认为写模式。或当调用clear()方法时表示转换成写模式。写模式状态下是谁来写是外部来写的外部文件IO网络IO会写入数据到Buffer缓冲区 读模式何时开启当调用flip()时改为读模式。读模式下是读到哪把Buffer缓冲区的数据读到JVM程序中。 无论读模式还是写模式都是相对于程序而言只不过这里把原有传统IO下使用流区分方向转变到现如今使用Buffer的读写模式来区分了 读模式下相对JVM程序而言是把Buffer数据读入到JVM程序的所以是读。 写模式下相对于JVM程序而言是把Buffer数据写出到外部(如文件)所以是写 代码 public class TestNIO1 {public static void main(String[] args) throws Exception{//1.创建ChannelFileChannel channel new FileInputStream(D:\\Daily_Code\\Netty_NEW\\data.txt).getChannel();//2.创建缓冲区ByteBuffer buffer ByteBuffer.allocate(10) ;//因为可能缓冲区一次无法读取完文件的所有字节所以要while循环读取可能多次反复读取到申请的缓冲区中while (true) {//在创建完缓冲区后默认是写模式//3.把通道内获取的文件数据写入缓冲区int read channel.read(buffer) ;//此时说明文件已读取完循环应该退出if(read -1) {break;}//4.程序读取buffer的内容数据后续的操作设置buffer为读模式buffer.flip();//5.循环读取缓冲区的数据while(buffer.hasRemaining()) {byte b buffer.get();//把字节转换成可视化的字符//UTF-8编码中一个字符占用1~4的字节大小。汉字日文韩文占用3个字节ASCII表的字符占用1个字节xxx字符占用2个字节一些少数语言字符占用4个字节System.out.println((char)b (char) b);}//6.设置buffer为写模式因为循环上去后需要写入缓冲区所以需要重新设置为写模式buffer.clear();}}}常见Buffer 1. ByteBuffer 2. CharBuffer 3. DoubleBuffer 4. FloatBuffer 5. IntBuffer 6. LongBuffer 7. ShortBuffer 8. MappedByteBuffer.. 最常用的就是ByteBuffer因为所有字符类型都可以转换成Byte字节格式。当然还有MappedByteBuffer Buffer缓冲区的获得方式 1.ByteBuffer.allocate(10) ---- 创建一个大小为10的Buffer缓冲区 2.encode() 3.3 第一个NIO程序 public class TestNIO1 {public static void main(String[] args) throws Exception{//1.创建ChannelFileChannel channel new FileInputStream(D:\\Daily_Code\\Netty_NEW\\data.txt).getChannel();//2.创建缓冲区ByteBuffer buffer ByteBuffer.allocate(10) ;//因为可能缓冲区一次无法读取完文件的所有字节所以要while循环读取可能多次反复读取到申请的缓冲区中while (true) {//在创建完缓冲区后默认是写模式//3.把通道内获取的文件数据写入缓冲区int read channel.read(buffer) ;//此时说明文件已读取完循环应该退出if(read -1) {break;}//4.程序读取buffer的内容数据后续的操作设置buffer为读模式buffer.flip();//5.循环读取缓冲区的数据while(buffer.hasRemaining()) {byte b buffer.get();//把字节转换成可视化的字符//UTF-8编码中一个字符占用1~4的字节大小。汉字日文韩文占用3个字节ASCII表的字符占用1个字节xxx字符占用2个字节一些少数语言字符占用4个字节System.out.println((char)b (char) b);}//6.设置buffer为写模式因为循环上去后需要写入缓冲区所以需要重新设置为写模式buffer.clear();}}} public class TestNIO2 {public static void main(String[] args) {//RandomAccessFile 异常处理FileChannel channel null ;try {//第一个参数指定文件的路径第二个参数指定文件的行使权力rw表示可读写, r表示可读w表示可写channel new RandomAccessFile(D:\\Daily_Code\\Netty_NEW\\data.txt,rw).getChannel() ;ByteBuffer buffer ByteBuffer.allocate(10) ;while (true) {int read channel.read(buffer) ;if(read -1) {break;}buffer.flip();while (buffer.hasRemaining()) {byte b buffer.get();System.out.println((char)b (char) b);}buffer.clear();}} catch (Exception e) {throw new RuntimeException(e);} finally {if(channel ! null) {try {channel.close();} catch (IOException e) {throw new RuntimeException(e);}}}}} public class TestNIO3 {public static void main(String[] args) {try(FileChannel channel FileChannel.open(Paths.get(D:\\Daily_Code\\Netty_NEW\\data.txt) , StandardOpenOption.READ);) {ByteBuffer buffer ByteBuffer.allocate(10) ;while (true) {int read channel.read(buffer) ;if(read -1) {break;}buffer.flip();while (buffer.hasRemaining()) {byte b buffer.get();System.out.println((char) b (char) b);}buffer.clear();}} catch (Exception e) {e.printStackTrace();}}}总结 细节总结 1. 三个案例代码分别采用不同创建Channel管道对象的方式并且要指定对Channel的读或写的权限 获取Channel的方式 (1) new FileInputStream(xxx).getChannel (2) new RandomAccessFile(xxx).getChannel() (3) FileChannel.open(xxx) 2.新语法的使用 3.5 NIO步骤总结 1.获取Channel 2.创建Buffer 3.循环的从Channel中获取数据写入到Buffer缓冲区进行操作
http://www.zqtcl.cn/news/287112/

相关文章:

  • 课程视频网站建设的必要性专利减缓在哪个网站上做
  • 正规品牌网站设计品牌网站建设开发 脚本语言
  • 潍坊模板建站定制网站规划管理部门的网站建设
  • 光明楼网站建设九一人才网赣州招聘官网
  • 如何做网站监控wordpress修改文章点赞数
  • 佛山高端网站建设报价网站的建设属于无形资产
  • 永川网站设计wordpress+用户前台
  • 晋城客运东站网站开发公司装修通知告示怎么写
  • 北京做手机网站的公司哪家好完整的网站开发
  • 建立网站的内容规划长沙网络推广哪家
  • 网站建设及优化教程百度网站优化排名
  • 医院网站推广渠道网站关键词排名不稳定
  • 类网站建设陕西省建设资格注册中心网站
  • 网站横幅图片网页设计怎么创建站点
  • 网站建设页面设计图片开个送快餐网站怎么做
  • 北京免费网站建设模板下载南江县建设局网站
  • 温岭手机网站建设义乌市网站建设
  • 西安网站制作费用哪家装修公司比较好的
  • 硅谷网站开发薪酬wordpress热门吗
  • 红酒营销型网站建设天一建设网站
  • 做网站建设公司哪家好安徽省住房建设部官方网站
  • 网站被黑咋样的柳州正规网站制作公司哪家好
  • 莱芜网站开发代理四川网络推广服务
  • 应该知道的网站网站全网建设莱芜
  • 北京网站页设计制作广州专业网站改版
  • 重庆网站建设建站收费免费外链网盘
  • 做加盟代理的网站比较好的网页网站设计
  • 兴义网站开发企业标准备案平台官网
  • 蓝彩网络科技_齐齐哈尔微信营销_齐齐哈尔网站建设会员卡管理系统哪里买
  • 织梦门户网站做大后建个人免费网站用哪个