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

SOFARPC(笔记)

文章目录

  • 一、快速开始
    • 1.1 SOFARPC
    • 1.2 基于SOFABoot
  • 二、注册中心
  • 三、通讯协议
    • 2.1 Bolt
      • 基本发布
      • 调用方式
      • 超时控制
      • 协议泛化调用
      • 序列化协议
      • 自定义线程池
    • 2.2 RESTful
      • 基本使用
    • 2.3 其他协议
    • 四、架构
  • 附录

官方样例下载地址-sofa-boot-guides

可查看 SOFARPC 方式快速入门

一、快速开始

1.1 SOFARPC

导入如下依赖

<dependency><groupId>com.alipay.sofa</groupId><artifactId>sofa-rpc-all</artifactId><version>最新版本</version>
</dependency>

版本查看

创建一个接口

public interface HelloService {String sayHello(String string);
}

实现它

public class HelloServiceImpl implements HelloService {@Overridepublic String sayHello(String string) {System.out.println("Server receive: " + string);return "hello " + string + " !";}
}

服务器代码

import com.alipay.sofa.rpc.config.ProviderConfig;
import com.alipay.sofa.rpc.config.ServerConfig;public class QuickStartServer {public static void main(String[] args) {ServerConfig serverConfig = new ServerConfig().setProtocol("bolt") // 设置一个协议,默认bolt.setPort(12200) // 设置一个端口,默认12200.setDaemon(false); // 非守护线程ProviderConfig<HelloService> providerConfig = new ProviderConfig<HelloService>().setInterfaceId(HelloService.class.getName()) // 指定接口.setRef(new HelloServiceImpl()) // 指定实现.setServer(serverConfig); // 指定服务端providerConfig.export(); // 发布服务}
}

客户端代码

import com.alipay.sofa.rpc.config.ConsumerConfig;public class QuickStartClient {public static void main(String[] args) {ConsumerConfig<HelloService> consumerConfig = new ConsumerConfig<HelloService>().setInterfaceId(HelloService.class.getName()) // 指定接口.setProtocol("bolt") // 指定协议.setDirectUrl("bolt://127.0.0.1:12200"); // 指定直连地址// 生成代理类HelloService helloService = consumerConfig.refer();while (true) {System.out.println(helloService.sayHello("world"));try {Thread.sleep(2000);} catch (Exception e) {}}}
}

在这里插入图片描述

1.2 基于SOFABoot

引入如下依赖

	<parent><groupId>com.alipay.sofa</groupId><artifactId>sofaboot-dependencies</artifactId><version>3.2.0</version></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.alipay.sofa</groupId><artifactId>rpc-sofa-boot-starter</artifactId></dependency></dependencies>

以及基本的SpringBoot配置

spring.application.name=rpcApp
logging.path=./logs
server.port=8080

服务接口

package com.SOFABootRPCTest.service;public interface AnnotationService {String sayAnnotation(String string);
}

服务实现接口

在前文中,我们用@Configuration、@Bean+@SofaService来完成的发布与引用,我们这里就直接用@Service+@SofaService的方式完成

package com.SOFABootRPCTest.serviceImpl;import com.SOFABootRPCTest.service.AnnotationService;
import com.alipay.sofa.runtime.api.annotation.SofaService;
import com.alipay.sofa.runtime.api.annotation.SofaServiceBinding;
import org.springframework.stereotype.Service;@SofaService(interfaceType = AnnotationService.class, uniqueId = "annotationServiceImpl", bindings = { @SofaServiceBinding(bindingType = "bolt")})
@Service
public class AnnotationServiceImpl implements AnnotationService {@Overridepublic String sayAnnotation(String string) {return string;}
}

bolt这里是协议,我们在前文中这个地方是jvm。不同协议用法不同。可以看到,默认是jvm协议。
在这里插入图片描述

上面代表我们的接口就正式发布了。可以通过互联网进行访问。


我们现在要调用我们发布的接口,基本和jvm一样。jvmFirst默认为True,也就是优先使用jvm协议。

package com.client;import com.alipay.sofa.runtime.api.annotation.SofaReference;
import com.alipay.sofa.runtime.api.annotation.SofaReferenceBinding;
import com.service.AnnotationService;
import org.springframework.stereotype.Component;@Component
public class AnnotationClientImpl {@SofaReference(interfaceType = AnnotationService.class, jvmFirst = false,uniqueId = "annotationServiceImpl",binding = @SofaReferenceBinding(bindingType = "bolt"))private AnnotationService annotationService;public String sayClientAnnotation(String str) {return annotationService.sayAnnotation(str);}
}

使用起来很像Fegin直接调用方法即可。

文档给的代码如下。也可以用 阿里官方给的 SOFARPC快速入门里面的代码。

将下列main中代码放入当前MainApplication中,即可。

package com.SOFABootRPCTest.client;import com.SOFABootRPCTest.Contoller.AnnotationClientImpl;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ApplicationContext;public class AnotationClientApplication {public static void main(String[] args) {// 临时切换地址,避免端口重复System.setProperty("server.port", "8081");SpringApplication springApplication = new SpringApplication(AnotationClientApplication.class);ApplicationContext applicationContext = springApplication.run(args);AnnotationClientImpl annotationService = applicationContext.getBean(AnnotationClientImpl.class);String result = annotationService.sayClientAnnotation("annotation");System.out.println("invoke result:" + result);}
}

在这里插入图片描述

二、注册中心

笔者使用Nacos作为注册中心,其他注册中心可参考注册中心

使用时注意版本要求

图方便可以用本地文件作为注册中心

三、通讯协议

我们此处仅尝试注解方式的发布引用。

可以自行参考协议基本使用

可以创建如下结构项目
在这里插入图片描述

2.1 Bolt

基本发布

api中创建

package com.serviceApi;public interface SampleService {String HelloWorld();
}

producer中创建

package com.producer.serviceImpl;import com.alipay.sofa.runtime.api.annotation.SofaService;
import com.alipay.sofa.runtime.api.annotation.SofaServiceBinding;
import com.serviceApi.SampleService;
import org.springframework.stereotype.Service;@Service
@SofaService(uniqueId = "sampleService",bindings = {@SofaServiceBinding(bindingType = "bolt")})
public class SampleServiceImpl implements SampleService {@Overridepublic String HelloWorld() {System.out.println("==========================\nhello world!\n==========================\n");return "hello world";}
}

consumer中使用

package com.consumer;import com.alipay.sofa.runtime.api.annotation.SofaReference;
import com.alipay.sofa.runtime.api.annotation.SofaReferenceBinding;
import com.serviceApi.SampleService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;@RunWith(SpringRunner.class)
@SpringBootTest(classes = ConsumerApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class test {@SofaReference(uniqueId = "sampleService",binding = @SofaReferenceBinding(bindingType = "bolt"))private SampleService sampleService;@Testpublic void testRPC(){sampleService.HelloWorld();}
}

我们启动服务producer服务,然后consumer使用Test(上述代码)

在这里插入图片描述
可以看到成功调用

使用端口可通过如下配置进行修改

com.alipay.sofa.rpc.bolt.port=端口号

调用方式

  • 同步

见前文

  • 异步

异步调用的方式下,客户端发起调用后不会等到服务端的结果,继续执行后面的业务逻辑。服务端返回的结果会被 SOFARPC 缓存,当客户端需要结果的时候,再主动调用 API 获取。

异步方式如下:

	package com.consumer;import com.alipay.sofa.rpc.api.future.SofaResponseFuture;
import com.alipay.sofa.runtime.api.annotation.SofaReference;
import com.alipay.sofa.runtime.api.annotation.SofaReferenceBinding;
import com.serviceApi.SampleService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;@RunWith(SpringRunner.class)
@SpringBootTest(classes = ConsumerApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class test {@SofaReference(uniqueId = "sampleService",binding = @SofaReferenceBinding(bindingType = "bolt",invokeType = "future"))private SampleService sampleService;@Testpublic void testRPC(){try {sampleService.HelloWorld();// true表示清除String result = (String) SofaResponseFuture.getResponse(10000, true);System.out.println(result);}catch (InterruptedException e) {throw new RuntimeException(e);}}
}

注意,观察源码会发现内部是用ThreadLocalMap,如果一个线程发布了两个异步请求,但其间没有获取结果,其结果后到的一项会覆盖前一项。

我们进行如下测试。

为SampleService再添一个实例

package com.producer.serviceImpl;import com.alipay.sofa.runtime.api.annotation.SofaService;
import com.alipay.sofa.runtime.api.annotation.SofaServiceBinding;
import com.serviceApi.SampleService;
import org.springframework.stereotype.Service;@Service
@SofaService(uniqueId = "sampleService2",bindings = @SofaServiceBinding(bindingType = "bolt"))
public class SampleServiceImpl2 implements SampleService {@Overridepublic String HelloWorld() {System.out.println("==========================\nhello Java!\n==========================\n");return "hello Java!";}
}

我们将测试部分改成这样的代码(睡眠了一秒为了保证前一项执行完毕)

package com.consumer;import com.alipay.sofa.rpc.api.future.SofaResponseFuture;
import com.alipay.sofa.runtime.api.annotation.SofaReference;
import com.alipay.sofa.runtime.api.annotation.SofaReferenceBinding;
import com.serviceApi.SampleService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;@RunWith(SpringRunner.class)
@SpringBootTest(classes = ConsumerApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class test {@SofaReference(uniqueId = "sampleService",binding = @SofaReferenceBinding(bindingType = "bolt",invokeType = "future"))private SampleService sampleService;@SofaReference(uniqueId = "sampleService2",binding = @SofaReferenceBinding(bindingType = "bolt",invokeType = "future"))private SampleService sampleService2;@Testpublic void testRPC(){try {sampleService.HelloWorld();Thread.sleep(1000);sampleService2.HelloWorld();String result = (String) SofaResponseFuture.getResponse(10000, true);System.out.println(result);}catch (InterruptedException e) {throw new RuntimeException(e);}}
}

服务器端没有问题
在这里插入图片描述
结果却输出了hello Java
在这里插入图片描述

如果我们去两次会报错,说明确实覆盖了。(当然如果是false就不会被清除)

 public void testRPC(){try {sampleService.HelloWorld();Thread.sleep(1000);sampleService2.HelloWorld();String result = (String) SofaResponseFuture.getResponse(10000, true);String result2 = (String) SofaResponseFuture.getResponse(10000, true);System.out.println(result);System.out.println(result2);}catch (InterruptedException e) {throw new RuntimeException(e);}}

在这里插入图片描述

我们可以发布后交给Java原来的异步调用来管理。

			 Future future = SofaResponseFuture.getFuture(true);future.get(10000, TimeUnit.MILLISECONDS);
  • 回调

需要实现SofaResponseCallback类

package com.consumer.callback;import com.alipay.sofa.rpc.core.exception.SofaRpcException;
import com.alipay.sofa.rpc.core.invoke.SofaResponseCallback;
import com.alipay.sofa.rpc.core.request.RequestBase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;;@Configuration
public class CallbackConfiguration  {Logger log = LoggerFactory.getLogger(CallbackConfiguration.class);@Bean("sampleCallback")public  SofaResponseCallback getSampleCallback(){return new SofaResponseCallback() {@Overridepublic void onAppResponse(Object o, String s, RequestBase requestBase) {log.info("调用回调");log.info("{}",o.toString());}@Overridepublic void onAppException(Throwable throwable, String s, RequestBase requestBase) {System.out.println("APP错误");}@Overridepublic void onSofaException(SofaRpcException e, String s, RequestBase requestBase) {System.out.println("SOFA错误");}};}
}

SOFARPC 为设置回调接口提供了两种方式,

  • Callback Class:Callback Class 的方式直接设置回调的类名,SOFARPC 会通过调用回调类的默认构造函数的方式生成回调类的实例。
  • Callback Ref:Callback Ref 的方式则为用户直接提供回调类的实例。callbackRef 属性的值需要是回调类的 Bean 名称。

  • 单向

当客户端发送请求后不关心服务端返回的结果时,可以使用单向的调用方式,这种方式会在发起调用后立即返回 null,并且忽略服务端的返回结果。

使用单向的方式只需要将调用方式设置为 oneway 即可,设置方式和将调用方式设置为 future 或者 callback 一样,这里不再重复讲述,可以参考上面的文档中提供的设置方式。

需要特别注意的是,由于单向的调用方式会立即返回,所以所有的超时设置在单向的情况下都是无效的。

超时控制

使用 Bolt 协议进行通信的时候,SOFARPC 的超时时间默认为 3 秒,用户可以在引用服务的时候去设置超时时间,又分别可以在服务以及方法的维度设置超时时间,SOFARPC 的超时时间的设置的单位都为毫秒。

可自行查看-Bolt 协议超时控制

  • 服务维度

如果需要在发布服务的时候在服务维度设置超时时间,设置对应的 timeout 参数到对应的值即可。

@SofaReference(binding = @SofaReferenceBinding(bindingType = "bolt", timeout = 2000))
private SampleService sampleService;
  • 方法维度

注解模式暂无

协议泛化调用

发布可以不变

xml无法读入时,可以尝试如下方式(*代表查找所有,无*代表使用找到的第一个)

@ImportResource({ "classpath*:rpc-starter-example.xml" })

在引用时需要配置XML


<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:sofa="http://sofastack.io/schema/sofaboot"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://sofastack.io/schema/sofaboot http://sofastack.io/schema/sofaboot.xsd"default-autowire="byName"><sofa:reference jvm-first="false" id="sampleGenericServiceReference" interface="com.serviceApi.SampleService"><sofa:binding.bolt><sofa:global-attrs generic-interface="com.serviceApi.SampleService"/></sofa:binding.bolt>
</sofa:reference></beans>
	@Testpublic void testRPC() {GenericService sampleGenericServiceReference = (GenericService) SpringUtil.getBean("sampleGenericServiceReference");// 需要传入方法名,方法类型,方法参数String result = sampleGenericServiceReference.$genericInvoke("HelloWorld",new String[]{},new Object[]{},String.class);System.out.println(result);}

其他规则可参考官方给出的例子

/**
* Java Bean
*/
public class People {private String name;private int    age;// getters and setters
}/*** 服务方提供的接口*/
interface SampleService {String hello(String arg);People hello(People people);String[] hello(String[] args);
}/*** 客户端*/
public class ConsumerClass {GenericService genericService;public void do() {// 1. $invoke仅支持方法参数类型在当前应用的 ClassLoader 中存在的情况genericService.$invoke("hello", new String[]{ String.class.getName() }, new Object[]{"I'm an arg"});// 2. $genericInvoke支持方法参数类型在当前应用的 ClassLoader 中不存在的情况。// 2.1 构造参数GenericObject genericObject = new GenericObject("com.alipay.sofa.rpc.test.generic.bean.People"); // 构造函数中指定全路径类名genericObject.putField("name", "Lilei"); // 调用putField,指定field值genericObject.putField("age", 15);// 2.2 进行调用,不指定返回类型,返回结果类型为GenericObjectObject obj = genericService.$genericInvoke("hello", new String[]{"com.alipay.sofa.rpc.test.generic.bean.People"}, new Object[] { genericObject });Assert.assertTrue(obj.getClass == GenericObject.class);// 如果返回的是泛化的自定义对象,可以如下方式取出。String name = result.getField("name");// 2.3 进行调用,指定返回类型People people = genericService.$genericInvoke("hello", new String[]{"com.alipay.sofa.rpc.test.generic.bean.People"}, new Object[] { genericObject }, People.class);// 2.4 进行调用,参数类型是数组类型String[] result = (String[]) proxy.$genericInvoke("hello", new String[]{new String[0].getClass().getName()}, new Object[]{ new String[]{"args"} });}
}

序列化协议

SOFARPC 可以在使用 Bolt 通信协议的情况下,可以选择不同的序列化协议,

  • hessian2
  • protobuf

默认的情况下,SOFARPC 使用 hessian2 作为序列化协议

配置

@SofaService(bindings = @SofaServiceBinding(bindingType = "bolt",serializeType = "protobuf"))
public class SampleServiceImpl implements SampleService {
}@SofaReference(binding = @SofaReferenceBinding(bindingType = "bolt", serializeType = "protobuf"))
private SampleService sampleService;

自定义线程池

SOFARPC 支持自定义业务线程池。可以为指定服务设置一个独立的业务线程池,和 SOFARPC 自身的业务线程池是隔离的。多个服务可以共用一个独立的线程池。

SOFARPC 要求自定义线程池的类型必须是 com.alipay.sofa.rpc.server.UserThreadPool。

配置

@SofaService(bindings = {@SofaServiceBinding(bindingType = "bolt", userThreadPool = "customThreadPool")})
public class SampleServiceImpl implements SampleService {
}

2.2 RESTful

基本使用

import javax.ws.rs.GET;
import javax.ws.rs.Path;@Path("/sample")
public interface SampleService {@GET@Path("/hello")String HelloWorld();
}
@Service
@SofaService(uniqueId = "sampleService",bindings = @SofaServiceBinding(bindingType = "rest"))
public class SampleServiceImpl implements SampleService {@Overridepublic String HelloWorld() {System.out.println("==========================\nhello world!\n==========================\n");return "hello world";}
}

上述代码需放在同一项目中。

可以使用浏览器访问

http://localhost:8341/sample/hello

SOFARPC 的 RESTful 服务的默认端口为 8341。

可配置进行修改

com.alipay.sofa.rpc.rest.port=端口号

也可以用如下方式调用

@RunWith(SpringRunner.class)
@SpringBootTest(classes = ConsumerApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class test {@SofaReference(uniqueId = "sampleService",binding = @SofaReferenceBinding(bindingType = "rest"))private SampleService sampleService;@Testpublic void testRPC(){System.out.println(sampleService.HelloWorld());}}

2.3 其他协议

除Http外,用法与Bolt类似。可参看协议基本使用

四、架构

在这里插入图片描述

附录

SOFARPC 方式快速入门
阿里云官方文档

相关文章:

SOFARPC(笔记)

文章目录 一、快速开始1.1 SOFARPC1.2 基于SOFABoot 二、注册中心三、通讯协议2.1 Bolt基本发布调用方式超时控制协议泛化调用序列化协议自定义线程池 2.2 RESTful基本使用 2.3 其他协议四、架构 附录 官方样例下载地址-sofa-boot-guides 可查看 SOFARPC 方式快速入门 一、快…...

无线上网连接及配置

目录 1. 无线上网连接及配置 1.1 无线路由器连接方式 ​编辑 1.2 无线路由器的基本配置 1.配置用户计算机上的IP地址 2.访问无线路由Web管理界面 1.3 WAN 口设置 1.动态 IP 2.静态 IP 1. 无线上网连接及配置 一小型公司共有20名员工。由于公司业务需要访问Internet&…...

Webpack减少打包数量和体积(Umi 3.*中)

在UMI 3.*中配置&#xff1a; export default defineConfig({chunks: [vendors, umi],chainWebpack: function (config: any, { webpack }: any) {config.plugin(chunkPlugin).use(webpack.optimize.LimitChunkCountPlugin, [{maxChunks: 5, // 必须大于或等于 1&#xff0c;此…...

python Crypto 包安装

经测试使用 pip install pycrypto安装会出现&#xff0c;如下所示错误&#xff1a; pip install pycrypto -i https://pypi.douban.com/simple/ Looking in indexes: https://pypi.douban.com/simple/ Collecting pycrypto Using cached https://pypi.doubanio.com/packages/…...

时序预测 | MATLAB实现SO-CNN-LSTM蛇群算法优化卷积长短期记忆神经网络时间序列预测

时序预测 | MATLAB实现SO-CNN-LSTM蛇群算法优化卷积长短期记忆神经网络时间序列预测 目录 时序预测 | MATLAB实现SO-CNN-LSTM蛇群算法优化卷积长短期记忆神经网络时间序列预测预测效果基本介绍程序设计学习总结参考资料 预测效果 基本介绍 时序预测 | MATLAB实现SO-CNN-LSTM蛇群…...

前端开发,怎么解决浏览器兼容性问题? - 易智编译EaseEditing

解决浏览器兼容性问题是前端开发中常见的挑战之一。不同的浏览器可能对网页元素的渲染和功能支持有所不同&#xff0c;因此需要采取一些策略来确保您的网页在不同浏览器上都能正常运行和呈现。以下是一些解决浏览器兼容性问题的方法和策略&#xff1a; 使用CSS Reset&#xff…...

树莓派3B安装64位操作系统

树莓派3B安装Ubuntu MATE_树莓派3b 安装ubuntu_雨田大大的博客-CSDN博客https://blog.csdn.net/lsjackson13/article/details/92423694?utm_mediumdistribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-0-92423694-blog-80716098.235%5Ev38%5Ep…...

Mysql系列 - 第2天:详解mysql数据类型(重点)

这是mysql系列第2篇文章。 环境&#xff1a;mysql5.7.25&#xff0c;cmd命令中进行演示。 主要内容 介绍mysql中常用的数据类型 mysql类型和java类型对应关系 数据类型选择的一些建议 MySQL的数据类型 主要包括以下五大类 整数类型&#xff1a;bit、bool、tinyint、smal…...

Linux常用的运维命令

1.查看进程按内存从大到小排序 ps -e -o "%C:%p:%z:%a"|sort -k5 -nr2.查看磁盘和分区信息 # 查看挂接的分区状态mount | column -t# 查看所有分区 fdisk -l# 查看所有交换分区 swapon -s3.查看网络信息 ifconfig # 查看所有网络接口的属性iptables -L…...

【从零学习python 】50.面向对象编程中的多态应用

文章目录 多态场景代码实现多态总结 进阶案例 多态 面向对象的三大特性&#xff1a; 封装&#xff1a;这是定义类的准则&#xff0c;根据对象的特点&#xff0c;将行为和属性抽象出来&#xff0c;封装到一个类中。继承&#xff1a;这是设计类的技巧。父类与子类&#xff0c;主…...

实现Token刷新机制

问题场景&#xff1a; 开发的项目中&#xff0c;如果正在项目中编辑信息&#xff0c;编辑信息的时间的过程中token失效可能导致信息丢失怎么办? 一、解决方法 实现Token刷新机制&#xff1a;客户端定时刷新token&#xff0c;当用户的token即将过期时&#xff0c;可以向服务器…...

FlaUi输入账号密码

FlaUI是一个用于自动化Windows桌面应用程序的开源UI自动化库&#xff0c;通常用于自动化Windows应用程序的测试和操作。如果你想使用FlaUI来输入账号和密码&#xff0c;你需要编写一些C#或其他支持.NET的编程代码来实现这一目标。以下是一个使用FlaUI来输入账号和密码的简单示例…...

ModStartBlog v8.0.0 博客归档页面,部分组件升级

ModStart 是一个基于 Laravel 模块化极速开发框架。模块市场拥有丰富的功能应用&#xff0c;支持后台一键快速安装&#xff0c;让开发者能快的实现业务功能开发。 系统完全开源&#xff0c;基于 Apache 2.0 开源协议。 功能特性 丰富的模块市场&#xff0c;后台一键快速安装会…...

使用 PyTorch 进行高效图像分割:第 4 部分

一、说明 在这个由 4 部分组成的系列中&#xff0c;我们将使用 PyTorch 中的深度学习技术从头开始逐步实现图像分割。本部分将重点介绍如何实现基于视觉转换器的图像分割模型。 图 1&#xff1a;使用视觉转换器模型架构运行图像分割的结果。 从上到下&#xff0c;输入图像、地面…...

西班牙卡瓦起泡酒的风味搭配

卡瓦是一种对食物友好的西班牙起泡酒&#xff0c;它的制作方法和香槟一样&#xff0c;可以和类似的食物搭配。卡瓦食物搭配包括各种食物&#xff0c;从海鲜和鱼到火腿&#xff0c;以及不同类型的小吃&#xff0c;也可以将卡瓦酒与甜点、水果和奶酪搭配。 卡瓦酒是世界上最著名的…...

Java项目-苍穹外卖-Day05

文章目录 1. 新增套餐1.1 需求分析和设计1.2 代码实现1.2.1 DishController1.2.2 DishService1.2.3 DishServiceImpl1.2.4 DishMapper1.2.5 DishMapper.xml1.2.6 SetmealController1.2.7 SetmealService1.2.8 SetmealServiceImpl1.2.9 SetmealMapper1.2.10 SetmealMapper.xml1.…...

取模运算符在数组下标的应用

什么是取模运算符%&#xff1f; 定义&#xff1a; a mod b&#xff0c;设a、b属于正整数且b>0&#xff0c;如果q、r属于正整数满足aq*br&#xff0c;且0≤r<b&#xff0c;则定义&#xff1a; a mod b r 注意&#xff1a;取模运算符两侧的除数和被除数都是整数&#xff…...

Firefox(火狐),使用技巧汇总,问题处理

本文目的 说明火狐如何安装在C盘之外的盘&#xff0c;即定制安装路径。如何将同步功能切换到本地服务上。默认是国际服务器。安装在C盘之后如何解决&#xff0c;之前安装的扩展无法自动同步的问题。顺带讲解一下&#xff0c;火狐的一些比较好用的扩展。 安装路径定制 火狐目前…...

耐腐蚀高速数控针阀和多功能PID控制器在流量比率控制中的应用

摘要&#xff1a;在目前的流体比值混合控制系统中&#xff0c;普遍采用的是多通道闭环PID控制系统对各路流量进行准确控制后再进行混合&#xff0c;这种控制方式普遍存在的问题是对流量调节阀的响应速度、耐腐蚀性和线性度有很高要求。为此本文提出的第一个解决方案是采用NCNV系…...

C语言:选择+编程(每日一练Day6)

目录 ​编辑选择题&#xff1a; 题一&#xff1a; 题二&#xff1a; 题三&#xff1a; 题四&#xff1a; 题五&#xff1a; 编程题&#xff1a; 题一&#xff1a;至少是其他数字两倍的最大数 思路一&#xff1a; 思路二&#xff1a; 题二&#xff1a;两个数组的交集…...

微信小程序教学系列(8)

微信小程序教学系列 第八章&#xff1a;小程序国际化开发 欢迎来到第八章&#xff01;这一次我们要谈论的是小程序国际化开发。你可能会问&#xff0c;什么是国际化&#xff1f;简单来说&#xff0c;国际化就是让小程序能够适应不同的语言和地区&#xff0c;让用户们感受到更…...

情人节定制:HTML5 Canvas全屏七夕爱心表白特效

❤️ 前言 “这个世界乱糟糟的而你干干净净可以悬在我心上做太阳和月亮。”&#xff0c;七夕节表白日&#xff0c;你要错过吗&#xff1f;如果你言辞不善&#xff0c;羞于开口的话&#xff0c;可以使用 html5 canvas 制作浪漫的七夕爱心表白动画特效&#xff0c;全屏的爱心和…...

操作系统-笔记-第五章-输入输出管理

目录 五、第五章——输入输出管理 1、IO设备的概念和分类 &#xff08;1&#xff09;IO设备分类——使用特性 &#xff08;2&#xff09;IO设备分类——传输速率 &#xff08;3&#xff09;IO设备分类——信息交换&#xff08;块、字符&#xff09; 2、IO控制器 &#x…...

感觉自己效率不高吗?学习实现目标的六个关键步骤,让你做任何事都事半功倍!

概述 是否感觉自己效率不高?做任何事情都提不起来精神?开发的时候要完成的功能很多,却不知该如何下手去做?那么你通过这篇文章可以学习到六个完成工作和学习目标的关键步骤,只要简单重复这六个步骤,就可以很轻松的达到你想做到的任何目标。是不是感觉很神奇,我也是亲测…...

【高级IO】- 五种 IO 模型 | 多路转接 - select

目录 IO的基本概念 什么是高效的IO&#xff1f; 五种IO模型 阻塞IO 非阻塞IO 信号驱动IO IO多路转接 异步IO 同步通信VS异步通信&#xff08;synchronous communication / asynchronous communication&#xff09; 同步通信VS同步与互斥 阻塞VS非阻塞 其他高级IO …...

在Linux搭建GitLab私有仓库配置实现远程访问私有仓库Gitlab ——【内网穿透】

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《高效编程技巧》《cpolar》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 前言1. 下载Gitlab2. 安装Gitlab3. 启动Gitlab4. 安装cpolar5. 创建隧道配置访问地址6. 固定GitLab访问地址6.1 保留…...

ChatGPT应用于高职教育的四大潜在风险

目前&#xff0c;ChatGPT还是一种仍未成熟的技术&#xff0c;当其介入高职教育生态后&#xff0c;高职院校师生在享受ChatGPT带来的便利的同时&#xff0c;也应该明白ChatGPT引发的风险也会随之进入高职教育领域&#xff0c;如存在知识信息、伦理意识与学生主体方面的风险与挑战…...

uni-app在组件中内嵌webView,实现自定义webView的大小,并处理页面中有webview时其他元素点击事件失效的问题

uni-app在组件中内嵌webView&#xff0c;实现自定义webView的大小&#xff0c;并处理页面中有webview时其他元素点击事件失效的问题 uni-app在组件中内嵌webView&#xff0c;实现自定义webView的大小 setWebviewTop() {// #ifdef APP-PLUSvar currentWebview this.$scope.$g…...

档案开发:增加查询和打卡按钮

档案开发&#xff1a;增加查询和打卡按钮 和单据开发的不同点 没有单据类型不是右击–>特性–>单据主表/单据子表&#xff0c;而是右击–>特性–>选择想要的接口访问器类型是NCVO不需要映射不是项目右键–>新建–>其他–>主子表单据结点&#xff0c;而是…...

redis基础细心讲解,一篇了解常用的缓存技术!

今日内容 redis 1. 概念 2. 下载安装 3. 命令操作1. 数据结构 4. 持久化操作 5. 使用Java客户端操作redis 6. 在ssm项目中使用缓冲进行CRUD操作Redis 1. 概念 redis是一款高性能的NOSQL系列的非关系型数据库 1.1.什么是NOSQL ​ NoSQL(NoSQL = Not Only SQL),意即“不仅仅…...

Three.js之几何体、高光材质、渲染器设置、gui

参考资料 阵列立方体和相机适配体验Threejs常见几何体简介…gui.js库(可视化改变三维场景) 知识点 注&#xff1a;基于Three.jsv0.155.0 长方体&#xff1a;oxGeometry球体&#xff1a;SphereGeometry圆柱&#xff1a;CylinderGeometry矩形平面&#xff1a;PlaneGeometry圆…...

UE4如何连接dmx---摇头矩阵灯具的创建

UE4如何连接dmx---摇头矩阵灯具的创建 开始创建库&#xff01; 然后我们开始创建多少个灯珠&#xff08;注意了&#xff1a;这是矩阵灯&#xff0c;是看灯珠的&#xff09; 那么这里我们创建6X6灯珠 下面设置灯珠的属性&#xff0c;灯珠有什么属性呢&#xff0c;只有颜色属性&…...

网络聊天室

一、项目要求 利用UDP协议&#xff0c;实现一套聊天室软件。服务器端记录客户端的地址&#xff0c;客户端发送消息后&#xff0c;服务器群发给各个客户端软件。 问题思考 客户端会不会知道其它客户端地址&#xff1f; UDP客户端不会直接互连&#xff0c;所以不会获知其它客…...

ChatGPT只是玩具:生成式人工智能在不同行业的应用

源自&#xff1a;IT经理网 生成式人工智能的十一个行业用例 打开生成式 AI的正确姿势 声明:公众号转载的文章及图片出于非商业性的教育和科研目的供大家参考和探讨&#xff0c;并不意味着支持其观点或证实其内容的真实性。版权归原作者所有&#xff0c;如转载稿涉及版权等问题&…...

RestFul的风格是什么

RestFul的风格是什么&#xff1f; 当我们谈论RESTful风格时&#xff0c;它指的是一种设计和构建网络应用程序的原则和约定。以下是RESTful风格的一些主要特点&#xff1a; 资源&#xff1a;将应用程序的功能封装为资源&#xff0c;每个资源都有一个唯一的标识符&#xff08;U…...

【自制C/C++小项目JuLongEditor】使用Windows控制台API来制作一个简单的文本编辑器

2023年8月22日&#xff0c;周二下午 昨天花了一个下午和晚上来制作的&#xff0c; 实现了一些基本的功能&#xff0c; 但由于代码只有130行&#xff0c;所以存在很多不足之处 GitHub&#xff1a;GitHub - JuLongZhiLu/JuLongEditor: C/C小项目&#xff0c;使用Windows控制台…...

中国芯,寻找新赛道迫在眉睫

北京华兴万邦管理咨询有限公司 商瑞 陈皓 近期国内半导体行业的热点可以用两个“有点多”来描述&#xff0c;一个是中国芯群体中上市公司股价闪崩的有点多&#xff0c;另一个是行业和企业的活动有点多。前者说明了许多国内芯片设计企业&#xff08;fabless商业模式&#xff09;…...

C++ 好用的格式化库--fmt

背景 fmt 库是一个开源的 C 格式化库&#xff0c;它提供了一种简洁、安全和高效的方式来进行字符串格式化。该库的设计目标是提供与 Python 的字符串格式化语法类似的功能&#xff0c;同时保持 C 的类型安全性和性能。 下载与安装 官网下载 fmt 官网地址&#xff1a;https:…...

微信小程序教学系列(3)

微信小程序教学系列 第三章&#xff1a;小程序高级开发技巧 1. 小程序API的使用 小程序API简介 小程序API是小程序提供的一系列接口&#xff0c;用于实现各种功能和操作。通过调用小程序API&#xff0c;可以实现页面跳转、数据存储、网络请求等功能。 使用小程序API的步骤…...

ORB-SLAM系列算法演进

ORB-SLAM算法是特征点法的代表&#xff0c;当前最新发展的ORB-SLAM3已经将相机模型抽象化&#xff0c;适用范围非常广&#xff0c;虽然ORB-SLAM在算法上的创新并不是很丰富&#xff0c;但是它在工程上的创新确实让人耳目一新&#xff0c;也能更好的为AR、机器人的算法实现落地。…...

solidity0.8.0的应用案例11:透明代理合约

选择器冲突 智能合约中,函数选择器(selector)是函数签名的哈希的前4个字节。例如mint(address account)的选择器为bytes4(keccak256("mint(address)")),也就是0x6a627842. 由于函数选择器仅有4个字节,范围很小,因此两个不同的函数可能会有相同的选择器,例如…...

最新消息:谷歌将在Chromebook上运用UWB技术,无线通信更上一层

超宽带&#xff08;UWB&#xff09;技术是一种创新的短距离无线通信技术&#xff0c;具有高速数据传输和精确定位物体位置的优势。尽管该技术已经存在一段时间&#xff0c;但最近开始广泛应用于各种设备中。据最新报道&#xff0c;Pixel Watch 2可能会搭载UWB模块&#xff0c;这…...

php+echarts实现数据可视化实例3

效果 全部代码 <?php include(includes/session.inc); include(includes/SQL_CommonFunctions.inc); ?> <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" …...

ubuntu下安装Sphinx,编译pdf

安装WSL2&#xff1a; 以管理员身份打开PowerShellwsl --install 来安装其他 Linux 发行版wsl --list --verbose 查看安装在 Windows 计算机上的 Linux 发行版列表 安装sphinx&#xff1a; sudo apt-get updatesudo apt-get install python3-sphinxsudo apt-get install lat…...

vue2.x项目从0到1(七)之用户权限

此章节偏理论知识 对于小一点的项目 比如说角色都是平级的 那我们直接像之前 vue2.x项目从0到1&#xff08;二&#xff09;之后台管理侧边栏&#xff08;动态渲染路由以及高亮&#xff09;_vue动态渲染侧边栏_关忆北_的博客-CSDN博客这样渲染就行了 但是一旦项目大了 …...

上传镜像到阿里云的ACR

1、开通阿里云ACR 2、在ACR 中创建命名空间 3、本地安装docker 4、登录到 开通ACR&#xff0c;需要配置访问凭证 [rootmaster ~]# docker login --username***lb registry.cn-beijing.aliyuncs.com Password: 5、给镜像打标签 [rootmaster ~]# docker images REPOSITORY …...

ahooks.js:一款强大的React Hooks库及其API使用教程(五)

一、ahooks.js简介二、ahooks.js安装三、继续ahooks.js API的介绍与使用教程61. useEventTarget62. useExternal63. useFavicon64. useMutationObserver65. useLongPress66. useScroll67. useResponsive68. useFocusWithin69. useControllableValue70. useEventEmitter 一、aho…...

MySQL TCL 事务控制

文章目录 1.事务四大特性2.事务并发问题3.事务隔离级别4.隔离级别查看与设置5.动提交事务5.1 查看自动提交事务5.2 关闭或开启自动提交事务 6.事务执行的基本流程7.设置事务的保存点参考文献 说到事务控制&#xff0c;先说一下数据库的事务是什么以及 MySQL 中我们必知的知识点…...

【Ubuntu】从Graylog到Grafana Loki:构建更强大的网络设备管理和监控系统

在将Graylog部署到生产环境时&#xff0c;我们遇到了一些问题&#xff0c;其中最主要的是无法安装MongoDB并且无法随时重启机器去修改BIOS设置来修复问题 【WARNING: MongoDB 5.0 requires a CPU with AVX support, and your current system does not appear to have that! 】。…...

[JavaWeb]【八】web后端开发-Mybatis

目录 一 介绍 二 Mybatis的入门 2.1 快速入门 2.1.1 准备SpringBoot工程 2.1.2 创建数据库mybatis以及对应库表user 2.1.3 创建User实体类 2.1.4 配置application.properties数据库连接信息 2.1.5 编写sql语句&#xff08;注解方式&#xff09; 2.1.6 测试运行 2.1.7 配…...