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

gRPC简介

grpc简介

grpc介绍可以参考官网。无论是rpc还是grpc,可以这样理解,都知道过去使用的单单体架构,而在2011年5月威尼斯的一个软件架构会议上提出了微服务架构,围绕业务功能进行组织(organized around business capability),不再是以前的纵向切分,而改为按业务功能横向划分,一个微服务最好由一个小团队针对一个业务单元来构建。
在这里插入图片描述
所以服务和服务之间存在调用关系,服务中之间使用http调用,发现性能太差,使用了一种新的通信方式,这个通信方式称为rpc客户端和服务端沟通的过程如下:

  1. 客户端发送数据(以字节流的方式)编码
  2. 服务端接受并解析,根据约定执行什么然后把结果返回给客户,解码
    那RPC的发展,RPC远程调用总体而言:
  3. rpc就是上述的过程封装下,时期操作更加优化
  4. 使用一些大家都认可的协议,使其规范化
  5. 做成一些框架,直接或间接的产生利益,这个就是grpc

grpc是基于“服务定义”的思想,简单的来说,就是通过某种方式描述一个服务,这种描述与语言无关,在这个“服务定义”的过程中,描述了提供的服务名是什么,有哪些方法可以被调用,这些方法有哪些参数,返回参数是什么

grpc调用方称之为client,服务方为server。也就是说定义好了这些方法和服务之后,grpc会屏蔽底层的细节,client只需要调用定义好的防范,就能返回预期的结果,对server段来说,还需要实现定义的方法。

proto创建

这里结合grpc-study实例介绍,按照如下目录创建工程和文件,仅有hello.proto中存在代码
在这里插入图片描述

proto是一种语法,类似go中约定变量定义var name string一样,python中variable=1一样的语法规定。proto中也有自己的语法,比如使用message,使用service关键字, hello.proto代码如下:

syntax = "proto3";// 这部分内容是关于最后生成的go文件的是放在哪个目录哪个包中的, "."代表在当前目录生成,service代表了生成go文件的包名是service
option go_package=".;service";// 这里定义一个服务,这个份服务需要有一个方法,这个方法可以接受客户端的参数请求,再返回服务端的响应,这个方法是以rpc,就像func标记一个函数一行,这个rpc标记的是一个rpc的方法
// 其实可以看出,定义了一个service,称之为SayHello,这个服务有一个rpc的方法,名为SayHello
// 这个方法会发送一个HelloRequest,然后返回一个 HelloResponse
service SayHello {rpc SayHello(HelloRequest) returns (HelloResponse) {}
}// 既然是约定的一些规则,这里需要使用message关键字顶一个结构体,这个message类似go中的struct
// 这里比较特殊的是变量后的赋值,这里不是赋值,而是在定义这个变量在这个message中的位置,可以理解为显示的定义了该参数在message数组或者结构体的索引位置
// 最终生成代码的时候,就会根据标识号来生成对应的位置,如requestName在第一个位置就会生成在第一个
message HelloRequest {string requestName = 1;
}message HelloResponse {string response = 1;
}// 以上是一个约束规则,就是一个语法规定

terminal切换到 grpc-service下

grpc-study % cd hello-server\proto

切换该目录后,在和*.proto同级目录执行如下命令

protoc --go_out=. hello.proto  // 使用go_out生成需要的go语言的文件
protoc --go-grpc_out=. hello.proto // 使用go_out生成需要的rpc语言的文件

执行完成后,在proto下新增两个文件如下所示
在这里插入图片描述
对于远程过程调用,就使用的grpc中的代码。在这里插入图片描述
所以关于proto的总结如下:

  1. 创建工程项目,设置文件分层
  2. 编写proto文件
  3. (切换目录)使用go-out生成pb.go,使用go-grpc_out命令生成gprc.pb.go文件

proto文件介绍

message

message:protobul定义了一个消息类型是通过关键字message字段指定,消息就是要传输的数据格式的定义,message类似go中的struct,在消息中承载的数据分别对应的是一个字段,每个字段都有一个名字和一种类型。每个字段有一些规则:

  1. required:消息体中的必填字段,不设置时会导致编码异常,在protobf2中使用,在protobuf3中删除
  2. optional:消息体中的可选字段,protobuf3中取消了required和optional等说明关键字,默认都是optional
  3. repeated:消息中的可重复字段,重复的值的顺序会被保留在go中重复的会被定义为切片,使用repeadted可以理解为类似数组
    每个字段都必须有一个唯一的标识好,一般不建议一个消息号中超过15,当然消息也可以嵌套定义
message PersonInfomation {message Person {string name = 1;int32 height = 2;repeated int32 age = 3;}repeated Person info = 1;
}

如果要在父消息类型的外部重用这个消息类型,需要PersonInformation.Person的形式使用它,如:

message PersonMessage {PersonInformation.Person info  = 1;
}

既然是用于微服务,如果想要将消息类型用在RPC的系统中,可以在**.proto文件中定义一个RPC服务接口,protocol buffer编译器将会更具所选择的不同语言生成服务接口代码和存根

service SearchService {// rpc 服务函数名 (参数名)返回 (返回参数)rpc Search(SearchRquest) returns (SearchResponse)
}

这样就定义了了RCP的服务,该方法接受SearchRequest请求和SearchResponse响应.所以这个*.proto文件中的格式只是一个约定规定,就像go的函数使用func声明是一个函数,*.proto中也有自己的一些约束。有了这些约束之后,客户端和服务端都是去调用这些接口的,有了这些约束之后,grpc可以帮助我们去寻路,用什么方法写的,就调用什么方法就可以。

服务端实现

有了上面的*.proto的约束之后,就可以遵循该声明实现服务端的接口调用,服务端实现如下:

  • 创建gRPC Server对象,我们可以理解他是Server端的抽象对象
  • 将Server(包含需要被调用的服务端接口)注册到gRPC Server的内部注册中心,这样可以在服务端接受请求时,通过内部的服务发现,发现该服务器接口并转接进行逻辑处理
  • 创建Listen,监听TCP端口
  • gRPC Server开始lis.Accept,直到Stop
    上面定义了server中的方法,这里来具体实现,在serverice下的main.go中
package mainimport ("context""fmt""google.golang.org/grpc"pb "grpc-study/hello-server/proto""net"
)// hello server
type server struct {pb.UnimplementedSayHelloServer
}func (s *server) SayHello(ctx context.Context, req *pb.HelloRequest) (*pb.HelloResponse, error) {fmt.Printf("hello" + req.RequestName)return &pb.HelloResponse{Response: "hello" + req.RequestName}, nil
}func main() {//	开启端口监听listen, _ := net.Listen("tcp", "9090")//	把这个服务暴露其他服务使用grpcServer := grpc.NewServer()//在grpc服务端中去注册自己编写的服务pb.RegisterSayHelloServer(grpcServer, &server{})//创建服务完成后,启动该服务err := grpcServer.Serve(listen)if err != nil {fmt.Printf("failed to server: %", err)return}
}// 如何实现具体逻辑呢,在grpc.pb.go中找到源码,实现对应的方法逻辑就行了

客户端实现

有了上面的*.proto的约束之后,就可以遵循该声明实现服务端的接口调用,服务端实现如下:

  • 创建于给定目标(服务端)的连接交互
  • 创建server的客户端对象
  • 发送RPC对象,等待同步响应,得到回调后返回响应结果
  • 输出响应结果
package mainimport ("context""fmt""google.golang.org/grpc""google.golang.org/grpc/credentials/insecure"pb "grpc-study/hello-server/proto""log"
)func main() {// 连接打server端,次数禁用安全传输,没有加密和验证conn, err := grpc.Dial("127.0.0.1:9090", grpc.WithTransportCredentials(insecure.NewCredentials()))if err != nil {log.Fatalf("did not connect: %v", err)}defer conn.Close()//建立连接client := pb.NewSayHelloClient(conn)// 执行rpc调用(这个方法时在服务器端来实现并返回结果)resp, _ := client.SayHello(context.Background(), &pb.HelloRequest{RequestName: "zhiyu"})fmt.Println(resp.GetResponse())
}

先执行server中的main.go,再执行执行client中的main.go,检查执行结果,未来只要能找到"127.0.0.:9090"这个地址就可以调用到服务并可以拿到返回结果。goland IDE界面分屏执行两个main.go函数
在这里插入图片描述

这里注意到client/main.go中

func main() {// 连接打server端,此处禁用安全传输,没有加密和验证conn, err := grpc.Dial("127.0.0.1:9090", grpc.WithTransportCredentials(insecure.NewCredentials()))if err != nil {log.Fatalf("did not connect: %v", err)}

只要能访问到该地址信息,就可以拿到返回结果,因此这种是不安全的,所以需要进行加密+安全传输。
经过前文的学习,我们直到gRPC是一个C/S模型,需要开户客户端和服务端,客户端和服务端需要达成协议,使用某一个确认的传输协议来传输数据,gPRC通过默认使用protobuf作为传输协议,当然也可以使用其他的自定义协议创建,如你可以使用xml。接着再看grpc官网中的这个示意图,就可以如下表示:
在这里插入图片描述

客户端和服务端通信之前,客户端如何知道自己的数据发送给哪个明确的服务端呢?反过来,服务端是如何知道将数据返回给谁呢,这个就需要gRPC认证。
此处说到的认证,不是用户的身份认证,而是指多个server和多个client之间,如何识别对方是谁,并且可以安全的进行数据传输,可以通过如下的几种方式:

  • SSL/TLS认证方式(采用http2协议)
  • 基于Token的认证方式(基于安全连接)
  • 不采用任何措施的连接,这是不安全的连接(默认采用http1)
  • 自定义的身份认证
    客户端和服务端之间调用,我们可以通过加入证书的方式,实现调用的安全性
    TLS(Transport Layer Security,安全传输层),TLS是建立在传输层TCP协议之上的协议,服务于应用层,它的前身是SSL(Secure Socket Layeer,
    安全套接字层),它实现了将应用层的报文进行加密后再交由TCP进行传输的功能。
    TLS协议主要解决如下三个网络安全问题。
  1. 保密(message privacy),保密通过加密encryption实现,所有信息都加密传输,第三方无法嗅探;
  2. 完整性(message integrity),通过MAC校验机制,一旦被篡改,通值双方会立刻发现;
  3. 认证(mutual authentication),双方认证,双方都可以配备证书,防止身份被冒充
    生存环境可以购买证书或者使用一些平台发放的证书
  • key:服务器上的私钥文件,用于对发送给客户端数据的加密,以及对从客户端接受到数据的解密
  • csr:证书签名请求文件,用于提交给证书颁发机构(CA)对证书签名。
  • crt:由证书颁发机构(CA)签名后的证书,或者是开发者自签名的证书,包含证书持有人的信息,持有人的公钥,以及签署者的签名等信息
  • pem:是基于Base64编码的证书格式,扩展名包括PEM、CRT和CER

SSL/TLS认证方式

首先通过openssl生成证书和私钥,关于认证方式参考:https://www.kuangstudy.com/bbs/1604044550878703617

  1. 官网下载:https://www.openssl.org/source/ ,便捷版安装包http://slproweb.com/products/Win320penSSL.html
  2. 我们使用便捷版安装包,一直下一步即可
  3. 配置环境变量 D:\Environment\OpenSSL-Win64\bin
  4. 命令行测试 openssl

生成证书步骤如下,mac安装ssl参考:https://www.freesion.com/article/7165613046/

#1、生成私钥
openssl genrsa -out server.key 2048
#2、生成证书全部回车即可,可以不填
openss1 req -new -x509 -key server.key -out server.crt -days 36500
#国家名称
Country Name (2 letter code) [AU] :CN
#省名称
State or Province Name (full name) [Some-State]:GuangDong
#城市名称
Locality Name (eg, city) []:Meizhou
#公司组织名称
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Xuexiangbar
#部门名称
Organizational Unit Name (eg, section) []:go
#服务器or网站名称
Common Name
# 邮件
(e.g. server FQDN or YOUR name) []:kuangstudy
Email Address []:24736743@qq.com# 3、生存csr
openssl req -new -key server.key -out server.cs
#更改openssl.cnf (Linux 是openssl.cfg)
#1)复制一份你安装的openssl的bin目录里面的openssl.cnf 文件到你项目所在的目录
#2)找到[CA_default],打开 copy_extensions=copy(就是把前面的#去掉)
#3)找到[req],打开 req_extensions=v3_req # Thhe extensions to add to a certificate request
#4)找到[v3_req],添加 subjectAltName=@alt_namnes
#5)添加新的标签[alt_names],和标签字段
DNS.1 = *.zhiyu.com

这个就是对应未来通过zhiyu.com这个域名去访问才能同意,相当于是一个安全性的校验,客户端发起请求的时候需要携带该域名,这就是安全机制校验

相关文章:

gRPC简介

grpc简介 grpc介绍可以参考官网。无论是rpc还是grpc,可以这样理解,都知道过去使用的单单体架构,而在2011年5月威尼斯的一个软件架构会议上提出了微服务架构,围绕业务功能进行组织(organized around business capability)&#xf…...

《MySQL系列-InnoDB引擎25》表-InnoDB逻辑存储结构

InnoDB逻辑存储结构 从InnoDB存储引擎的逻辑存储结构看,所有数据都被逻辑地存放在一个空间中,称之为表空间(tablespace)。表空间又由段(segment)、区(extent)、页(page)组成。页在一些文档中有时也称为块(block),InnoDB存储引擎的逻辑存储结构…...

YOLOv8之C2f模块——与YOLOv5的C3模块对比

一、源码对比 YOLOv8完整工程代码下载:ultralytics/ultralytic   C2f模块源码在ultralytics/nn/modules.py下,源码如下: class C2f(nn.Module):# CSP Bottleneck with 2 convolutionsdef __init__(self, c1, c2, n1, shortcutFalse, g1, e…...

动态规划实例——换零钱的方法数(C++详解版)

原写了 Java 版本的如何求解换钱的方法数,近期进行了一些细节上的补充,以及部分错误更正,将语言换为了 C 语言。 基础题目 假设你现在拥有不限量的 1 元、5 元、10 元面值纸币,路人甲希望找你换一些零钱,路人甲拿出的…...

linux c

射频驱动 管理硬件设备、分配系统资源 内核由中断服务程序 调度程序 内存管理程序 网络和进程间进程通信程序 linux支持动态加载内核模块 支持多处理smp机制 内核可以抢占preemptive linux系统拥有多个发行版,可能由一个组织 公司和个人发行 VGA兼容或者更…...

第十三章 系统错误消息 - 一般系统错误消息 S - Z

文章目录第十三章 系统错误消息 - 一般系统错误消息 S - Z第十三章 系统错误消息 - 一般系统错误消息 S - Z 错误代码描述<SUBSCRIPT>下标值不合法或Global引用过长。<SWIZZLE FAIL>打开了一个oref&#xff0c;然后试图在另一个无法引用的相关对象中进行搅拌。这可…...

移动web基础

初始缩小&#xff1a;布局视口大于视觉视口 初始放大&#xff1a;布局视口小于视觉视口 布局视口等于视觉视口&#xff08;这种动作行为叫做理想视口&#xff09; <meta name"viewport" content"width375" /> <meta name"viewport"…...

MyBatis和MyBatis_Plus有什么区别【面试常考题】

MyBatis和MyBatis_Plus的区别 MyBatis_Plus MyBatis_Plus 是一个 MyBatis 的增强工具&#xff0c;只是在 MyBatis 的基础上增强了却没有做改变&#xff0c;MyBatis-Plus支持所有MyBatis原生的特性&#xff0c;所有引入MyBatis-Plus不会对现有的MyBatis框架产生任何影响。 MyBa…...

华为OD机试用Python实现 -【统一限载货物数最小值】(2023-Q1 新题)

华为OD机试题 华为OD机试300题大纲统一限载货物数最小值题目描述输入描述输出描述说明示例一输入输出说明示例二输入输出说明Python 代码实现算法逻辑华为OD机试300题大纲 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。 华为 OD 清单查…...

Vue入门小练习

文章目录Hello VueVue文本指令Vue属性绑定Vue双向绑定Vue事件绑定Vue猜数字Vue简单计算器Vue简单计算器升级版Vue循环遍历Vue员工列表练习Vue小练习Vue显示隐藏相关使用一些简单的小案例来熟悉Vue的基本使用方法 Hello Vue <!DOCTYPE html> <html lang"en"…...

Oracle-09-集合运算符篇

2022年4月13日23:01:25 通过本章学习,您将可以:1、描述 SET 操作符2、将多个查询用 SET 操作符连接组成一个新的查询目录 🏆一、SET OPERATORS ⭐️1.1、UNION /UNION ALL ⭐️1.2、INSTERSECT ⭐️1.3、MINUS dz...

获取浏览器(服务端)请求中特定的Cookie

有必要解释一下HttpServletRequest接口&#xff0c;因为我们需要从它里面获取Cookie。 HttpServletRequest HttpServletRequest是一个Java接口&#xff0c;提供了访问HTTP请求信息的方法&#xff0c;例如HTTP方法、请求URI、头部、参数和会话属性。它是Java Servlet API的一部…...

c++11 标准模板(STL)(std::unordered_set)(九)

定义于头文件 <unordered_set>template< class Key, class Hash std::hash<Key>, class KeyEqual std::equal_to<Key>, class Allocator std::allocator<Key> > class unordered_set;(1)(C11 起)namespace pmr { templat…...

python实战应用讲解-【实战应用篇】文件操作(附python示例代码)

目录 知识储备 使用 python-libarchive-c 模块 创建压缩文件 解压文件 查看信息...

OpenCV-Python系列(二)—— 图像处理(灰度图、二值化、边缘检测、高斯模糊、轮廓检测)

一、【灰度图、二值化】 import cv2 img cv2.imread("lz2.png") gray_img cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 灰度图 # 二值化&#xff0c;(127,255)为阈值 retval,bit_img cv2.threshold(gray_img, 127, 255, cv2.THRESH_BINARY) cv2.imshow(photo1,im…...

ccc-台大林轩田机器学习基石-hw1

文章目录Question1-14Question15-PLAQuestion16-PLA平均迭代次数Question17-不同迭代系数的PLAQuestion18-Pocket_PLAQuestion19-PLA的错误率Question20-修改Pocket_PLA迭代次数Question1-14 对于有明确公式和定义的不需要使用到ml 智能系统在与环境的连续互动中学习最优行为策…...

hadoop03-MapReduce【尚硅谷】

大数据学习笔记 MapReduce 一、MapReduce概述 MapReduce是一个分布式运算程序的编程框架&#xff0c;是基于Hadoop的数据分析计算的核心框架。 MapReduce处理过程为两个阶段&#xff1a;Map和Reduce。 Map负责把一个任务分解成多个任务&#xff1b;Reduce负责把分解后多任务处…...

测牛学堂:软件测试python学习之异常处理

python的捕获异常 程序在运行时&#xff0c;如果python解释器遇到一个错误&#xff0c;则会停止程序的执行&#xff0c;并且提示一些错误信息&#xff0c;这就是异常。 程序停止执行并且提示错误信息&#xff0c;称之为抛出异常。 因为程序遇到错误会停止执行&#xff0c;有时…...

图神经网络--图神经网络

图神经网络 图神经网络图神经网络一、PageRank简介1.1互联网的图表示1.2PageRank算法概述1.3求解PageRank二、代码实战2.1引入库2.2加载数据&#xff0c;并构建图2.3计算每个节点PageRank重要度2.4用节点尺寸可视化PageRank值一、PageRank简介 PageRank是Google最早的搜索引擎…...

React useCallback如何使其性能最大化?

前言 React中最让人畅谈的就是其带来的灵活性&#xff0c;可以说写起来非常的舒服。但是也就是它的灵活性太强&#xff0c;往往让我们忽略了很多细节的地方&#xff0c;而就是这些细节的东西能进行优化&#xff0c;减小我们的性能开销。可以说刚学React和工作几年后写React的代…...

长尾关键词使用方法,通过什么方式挖掘长尾关键词?

当你在搜索引擎的搜索栏中输入有关如何使用长尾关键词的查询时&#xff0c;你可能希望有简单快捷的方式出现在搜索结果中&#xff0c;可以帮助你更好地应用seo。 不过&#xff0c;这里要记住一件事&#xff1a;SEO 策略只会为你的网站带来流量&#xff1b;在你的产品良好之前&a…...

【网络编程套接字(一)】

网络编程套接字&#xff08;一&#xff09;理解源IP地址和目的IP地址理解源MAC地址和目的MAC地址理解源端口号和目的端口号PORT VS PID认识TCP协议和UDP协议网络字节序socket编程接口socket常见APIsockaddr结构简单的UDP网络程序服务端创建套接字服务端绑定字符串IP VS 整数IP客…...

shell脚本入门

实习的时候第一个月的考核就是如何部署一个云资源&#xff0c;当时走的捷径&#xff08;杠杠的搜索能力hhhh&#xff09;找到了一个shell脚本一键部署&#xff0c;后来被leader问起来就如实说了&#xff0c;leader问有没有看懂shell脚本中的逻辑……&#xff08;没有&#xff0…...

【经典蓝牙】 蓝牙HFP层协议分析

HFP 概述 HFP概念介绍 HFP(Hands-Free Profile)&#xff0c; 是蓝牙免提协议&#xff0c; 可以让蓝牙设备对对端蓝牙设备的通话进行控制&#xff0c;例如蓝牙耳机控制手机通话的接听、 挂断、 拒接、 语音拨号等。HFP中蓝牙两端的数据交互是通过定义好的AT指令来通讯的。 &am…...

互联网摸鱼日报(2023-02-26)

互联网摸鱼日报&#xff08;2023-02-26&#xff09; InfoQ 热门话题 迁移工具 Air2phin 宣布开源&#xff0c;2 步迁移 Airflow 至 Dolphinscheduler 专访奇安信董国伟博士&#xff1a;目前开源安全的现状并不乐观&#xff0c;但其重要性已成各方共识 专访Brian Behlendorf&…...

关于程序员中年危机的一个真实案例

​ 关于中年危机&#xff0c;网上已经有了各种各样的解读。但是&#xff0c;这两天一个学员跟我简单几句聊天&#xff0c;却触发了对于中年危机的另一种思考。如果你曾经也有点迷茫&#xff0c;或许你可以稍微花几分钟看下这个故事。 一、无奈的故事 ​ 39岁还出来面试&#x…...

【fly-iot飞凡物联】(2):如何从0打造自己的物联网平台,使用开源的技术栈搭建一个高性能的物联网平台,目前在设计阶段。

目录前言1&#xff0c;fly-iot 飞凡物联2&#xff0c;mqtt-broker 服务3, 管理后台产品/设备设计4,数据存储目前使用mysql&#xff0c;消息存储到influxdb中5,规则引擎使用 ekuiper6, 总结和其他的想法前言 本文的原文连接是: https://blog.csdn.net/freewebsys/article/detail…...

Hadoop MapReduce

目录1.1 MapReduce介绍1.2 MapReduce优缺点MapReduce实例进程阶段组成1.3 Hadoop MapReduce官方示例案例&#xff1a;评估圆周率π&#xff08;PI&#xff09;的值案例&#xff1a;wordcount单词词频统计1.4 Map阶段执行流程1.5 Reduce阶段执行流程1.6 Shuffle机制1.1 MapReduc…...

时间复杂度和空间复杂度详解

有一堆数据需要排序&#xff0c;A要使用快速排序&#xff0c;B要使用堆排序&#xff0c;A认为自己的代码更高效&#xff0c;B也认为自己的代码更高效&#xff0c;在这种情况下&#xff0c;怎么来判断谁的代码更好一点呢&#xff1f;这时候就有了时间复杂度和空间复杂度。 目录 …...

【C++】面向对象---封装

【C】面向对象—封装 1.封装的意义 封装是C面向对象三大特性之一 封装的意义&#xff1a; 将属性和行为作为一个整体&#xff0c;表现生活的事物将属性和行为加以权限控制 封装意义一&#xff1a; 在设计类的时候&#xff0c;属性和行为写在一起&#xff0c;表现事物 语…...

垫江网站建设哪家好/制作网页的工具软件

图像分割—基于图的图像分割&#xff08;Graph-Based Image Segmentation&#xff09;Reference:Efficient Graph-Based Image Segmentation,IJCV 2004,MIT CodeGraph-Based Segmentation 是经典的图像分割算法&#xff0c;作者Felzenszwalb也是提出DPM算法的大牛。该算法是基于…...

自己做黄网站犯法吗/今日军事新闻报道

处理 由于不是 按到 insert 键导致的&#xff0c;所以怎么按 insert 键都没用 是由于 装了 Vs Vim 插件导致的&#xff0c;把插件卸载或者禁用进行 再次打开 VS 就可以了 步骤如图所示&#xff1a;...

楼凤网站怎么做的/深圳网站建设公司

“ 纸上得来终觉浅&#xff0c;绝知此事要躬行。”小马过河&#xff0c;是我小学二年级学过的一篇语文。这么多年来&#xff0c;我对该内容印象深刻&#xff0c;就像昨天刚学过一样。其文寓意切合我们本文的主题--纸上得来终觉浅&#xff0c;绝知此事要躬行。01—背景-声音天对…...

中国最火的网站/免费网络推广渠道

#基于ip设置 server{ listen 80; server_name 192.168.116.129; location /{     root /usr/etc/ngin/html/ip;     index index.html;   } } #基于域名 server{   listen 80;   server_name z.com;   location /{     root z.com;     index index.ht…...

做网站编程在程序/网站的营销策略

进程间通讯( IPC&#xff1a;Inter Processes Communication ) 一. 管道(PIPE) 管道是一种特殊类型的文件&#xff0c;在应用层体现为两个打开的文件描述符。 对于管道本身而言&#xff0c;不是普通的文件&#xff0c;不属于某个文件系统&#xff0c;其只存在于内存中&#xf…...

国外成人做视频网站有哪些/新闻头条最新消息今天发布

前言 马爸爸总结了一句话&#xff1a;跳槽&#xff0c;要么是钱不到位&#xff0c;要么是受了委屈。 我给自己这次的跳槽经历做了一个分析&#xff0c;希望能对那些想换工作的朋友有所帮助。 许多朋友想换工作&#xff0c;但是对“换工作”的理解可能仅限于写简历、投简历、…...