• 关于

    框架入口文件

    的搜索结果

问题

在zendstudio中建立第一个thinkphp框架时,加载入口文件路径总报错?报错

爱吃鱼的程序员 2020-06-08 21:35:09 0 浏览量 回答数 1

问题

模块入口问题

幸福量子 2019-12-01 20:03:25 936 浏览量 回答数 1

回答

一般控制器是通过路由而被包括的文件, 而且现在的php框架基本都是单入口的,其实框架中有包涵或者自动加载所需的类文件的。 答案来源网络,供参考,希望对您有帮助

问问小秘 2019-12-02 03:02:14 0 浏览量 回答数 0

阿里云爆款特惠专场,精选爆款产品低至0.95折!

爆款ECS云服务器8.1元/月起,云数据库低至1.5折,限时抢购!

回答

是可以实现的。如以下两个域名都绑定到了某空间`exampleA.comexampleB.com`文件目录:/空间根目录/exampleA A站点目录 /exampleA/application A站点应用目录 /exampleAindex.php A站点入口文件 将$system_path更改为正确路径 /exampleB B站点目录 /exampleB/application B站点应用目录 /exampleB/index.php B站点入口文件 将$system_path更改为正确路径 /ci_system CI框架 .htaccess 文件(如果主机服务器环境是apache):RewriteEngine on RewriteCond %{HTTP_HOST} ^(www.)?exampleA.com$ RewriteRule ^(.*) /exampleA/$1 [L] RewriteCond %{HTTP_HOST} ^(www.)?exampleB.com$ RewriteRule ^(.*) /exampleB/$1 [L]

落地花开啦 2019-12-02 02:50:48 0 浏览量 回答数 0

回答

正确的使用方法是请在框架的入口文件中定义常量。``

河南 2019-12-02 01:45:06 0 浏览量 回答数 0

问题

请问弹性WEB上如何部署ThinkPHP5.0框架?

闪亮小蘑菇 2019-12-01 21:16:50 1661 浏览量 回答数 1

问题

nginx服务器部署TP框架问题

1779988779978194 2019-12-01 19:29:18 461 浏览量 回答数 1

回答

那个评论写起来麻烦,还是再这里回答你:你要使用shell来调用javajava命令只能运行含有main方法的类。即使你使用其它的工具它的入口本质还是一个含有main方法的类。这点不用疑虑。如果你想你自己都可以进行封装比如你让含有main方法的类充当控制器角色,嘿嘿这个就考验你程序设计能力了。可以学习作框架一样分层什么的。比如你做一个 TestExecutor ,它含有main方法。然后在这个类里面根据传入的参数去判断你具体调用哪个测试类以及加载一些配置文件什么的。。。至于调用,你花哨一些增强你工具的性质。比如将参数什么的写入property文件或者xml用程序读取对于测试类的调用你就做一些接口或者抽象类什么的,然后给他们做一个适配器(设计模式),如果你愿意甚至可以封装Junit测试中的代码简化测试类编写时候的复杂度。然后你将你这个工程打成一个jar包,比如TestExecutor.jar至于实际的测试你在重新做一个工程,引入你做的包。这样适用范围更广。然后将你的测试工程也可以打成一个jar包加入到上面的CLASSPATH中调用的shell 就是 java -cp ${CLASSPATH} xxxx.TestExecutor 就可以了。也就是shell调用的是一个控制器,对于自己写的测试代码只是这个控制器调用的对象而已。工程没有bin路径。。。。这个不要紧,你只要知道java是执行class文件的就行。我给你说的那些路径只是一个例子。你想想不用IDE,只用editplus之类的编辑器和jdk如何变异运行一个java工程的?只要你能准确找到class就行。至于那些路径根据自己喜好去设置。不用理会。

杨冬芳 2019-12-02 03:10:30 0 浏览量 回答数 0

问题

PHP框架queryphp教程配置-配置报错

montos 2020-06-03 21:54:45 3 浏览量 回答数 1

问题

PHP框架queryphp教程:入门一 Hello World 配置好php环境 目录结构..:报错

kun坤 2020-06-14 15:47:53 0 浏览量 回答数 1

问题

MaxCompute用户指南:处理非结构化数据:前言

行者武松 2019-12-01 22:05:17 1095 浏览量 回答数 0

回答

一、框架机制spring mvc 和 struts2的加载机制不同:spring mvc的入口是servlet,而struts2是filter。1、Struts2采用Filter(StrutsPrepareAndExecuteFilter)实现,SpringMVC(DispatcherServlet)则采用Servlet实现。2、Filter在容器启动之后即初始化;服务停止以后销毁,晚于Servlet。Servlet在是在调用时初始化,先于Filter调用,服务停止后销毁。二、拦截机制1、Struts2a、Struts2框架是类级别的拦截,每次请求就会创建一个Action,和Spring整合时Struts2的ActionBean注入作用域是原型模式prototype(否则会出现线程并发问题),然后通过setter,getter吧request数据注入到属性。b、Struts2中,一个Action对应一个request,response上下文,在接收参数时,可以通过属性接收,这说明属性参数是让多个方法共享的。c、Struts2中Action的一个方法可以对应一个url,而其类属性却被所有方法共享,这也就无法用注解或其他方式标识其所属方法了2、SpringMVCa、SpringMVC是方法级别的拦截,一个方法对应一个Request上下文,所以方法直接基本上是独立的,独享request,response数据。而每个方法同时又何一个url对应,参数的传递是直接注入到方法中的,是方法所独有的。处理结果通过ModeMap返回给框架。b、在Spring整合时,SpringMVC的Controller Bean默认单例模式Singleton,所以默认对所有的请求,只会创建一个Controller,有应为没有共享的属性,所以是线程安全的,如果要改变默认的作用域,需要添加@Scope注解修改。三、性能方面SpringMVC实现了零配置,由于SpringMVC基于方法的拦截,有加载一次单例模式bean注入。而Struts2是类级别的拦截,每次请求对应实例一个新的Action,需要加载所有的属性值注入,所以,SpringMVC开发效率和性能高于Struts2。四、拦截机制Struts2有自己的拦截Interceptor机制,SpringMVC这是用的是独立的Aop方式,这样导致Struts2的配置文件量还是比SpringMVC大。五、配置方面spring MVC和Spring是无缝的。从这个项目的管理和安全上也比Struts2高(当然Struts2也可以通过不同的目录结构和相关配置做到SpringMVC一样的效果,但是需要xml配置的地方不少)。SpringMVC可以认为已经100%零配置。六、设计思想Struts2更加符合OOP的编程思想, SpringMVC就比较谨慎,在servlet上扩展。七、集成方面SpringMVC集成了Ajax,使用非常方便,只需一个注解@ResponseBody就可以实现,然后直接返回响应文本即可,而Struts2拦截器集成了Ajax,在Action中处理时一般必须安装插件或者自己写代码集成进去,使用起来也相对不方便。

小川游鱼 2019-12-02 01:50:39 0 浏览量 回答数 0

问题

入门一 Hello World 配置好php环境 目录结构 域名配置 编写代码 调试和配置:配置报错

kun坤 2020-06-02 15:07:13 0 浏览量 回答数 1

问题

三级等保评测涉及的文档和资质申请提供和使用

quanbanquan 2019-12-01 19:09:41 498 浏览量 回答数 2

回答

一、框架机制 spring mvc 和 struts2的加载机制不同:spring mvc的入口是servlet,而struts2是filter。 1、Struts2采用Filter(StrutsPrepareAndExecuteFilter)实现,SpringMVC(DispatcherServlet)则采用Servlet实现。 2、Filter在容器启动之后即初始化;服务停止以后销毁,晚于Servlet。Servlet在是在调用时初始化,先于Filter调用,服务停止后销毁。 二、拦截机制 1、Struts2 a、Struts2框架是类级别的拦截,每次请求就会创建一个Action,和Spring整合时Struts2的ActionBean注入作用域是原型模式prototype(否则会出现线程并发问题),然后通过setter,getter吧request数据注入到属性。 b、Struts2中,一个Action对应一个request,response上下文,在接收参数时,可以通过属性接收,这说明属性参数是让多个方法共享的。 c、Struts2中Action的一个方法可以对应一个url,而其类属性却被所有方法共享,这也就无法用注解或其他方式标识其所属方法了 2、SpringMVC a、SpringMVC是方法级别的拦截,一个方法对应一个Request上下文,所以方法直接基本上是独立的,独享request,response数据。而每个方法同时又何一个url对应,参数的传递是直接注入到方法中的,是方法所独有的。处理结果通过ModeMap返回给框架。 b、在Spring整合时,SpringMVC的Controller Bean默认单例模式Singleton,所以默认对所有的请求,只会创建一个Controller,有应为没有共享的属性,所以是线程安全的,如果要改变默认的作用域,需要添加@Scope注解修改。 三、性能方面 SpringMVC实现了零配置,由于SpringMVC基于方法的拦截,有加载一次单例模式bean注入。而Struts2是类级别的拦截,每次请求对应实例一个新的Action,需要加载所有的属性值注入,所以,SpringMVC开发效率和性能高于Struts2。 四、拦截机制 Struts2有自己的拦截Interceptor机制,SpringMVC这是用的是独立的Aop方式,这样导致Struts2的配置文件量还是比SpringMVC大。 五、配置方面 spring MVC和Spring是无缝的。从这个项目的管理和安全上也比Struts2高(当然Struts2也可以通过不同的目录结构和相关配置做到SpringMVC一样的效果,但是需要xml配置的地方不少)。 SpringMVC可以认为已经100%零配置。 六、设计思想 Struts2更加符合OOP的编程思想, SpringMVC就比较谨慎,在servlet上扩展。 七、集成方面 SpringMVC集成了Ajax,使用非常方便,只需一个注解@ResponseBody就可以实现,然后直接返回响应文本即可,而Struts2拦截器集成了Ajax,在Action中处理时一般必须安装插件或者自己写代码集成进去,使用起来也相对不方便。

问问小秘 2019-12-02 02:11:20 0 浏览量 回答数 0

回答

在函数计算服务使用 Java 编程,需要定义一个 Java 函数作为入口。Java 运行环境根据是否支持 HTTP 触发器分为 普通函数入口 和 HTTP 触发器函数入口 两种函数入口,为函数设置 HTTP 触发器后的函数入口形式会不同,这是为了方便处理发来的 HTTP request 请求并允许用户返回自定义 HTTP header。其中 普通函数入口 又分为 处理函数入口 和 initializer入口。 本文对 普通函数入口 和 HTTP 触发器函数入口 进行详细介绍: 普通函数入口 处理函数入口 StreamRequestHandler PojoRequestHandler initializer 入口 HTTP 触发器函数入口 Java 代码打包 普通函数入口 处理函数入口 用户在使用 Java 编程时,必须要实现函数计算提供的接口类,对于普通函数入口目前有 2 个预定义接口可选择: StreamRequestHandler以流的方式接受调用输入event和返回执行结果,用户需要从inputStream中读取调用函数时的输入,处理完成后把函数执行结果写入到outputStream中来返回。 PojoRequestHandler通过泛型的方式,用户可以自定义输入和输出的类型,但是它们必须是POJO类型。 StreamRequestHandler 一个最简单的处理函数定义如下: package example; import com.aliyun.fc.runtime.Context; import com.aliyun.fc.runtime.StreamRequestHandler; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class HelloFC implements StreamRequestHandler { @Override public void handleRequest( InputStream inputStream, OutputStream outputStream, Context context) throws IOException { outputStream.write(new String("hello world").getBytes()); } } 1. 包名/类名 包名和类名可以是任意的,但是需要与创建函数时的 “Handler” 字段相对应:上面的例子包名是 “example”,类名是 “HelloFC”,那么创建函数时指定的 Handler 为 example.HelloFC::handleRequest,”Handler” 的格式为 {package}.{class}::{method}。 实现的接口 用户的代码中必须要实现函数计算预定义的接口。上面的例子中实现了StreamRequestHandler,其中的 inputStream 参数是调用函数时传入的数据,outputStream 用于返回函数的执行结果。 context参数 context 参数中包含一些函数的运行时信息(例如 request id/临时 AK 等)。其类型是 com.aliyun.fc.runtime.Context。 返回值 实现StreamRequestHandler接口的函数通过outputStream参数返回执行结果 引入接口库 其中用到的com.aliyun.fc.runtime这个包的依赖可以通过下面的 pom.xml 引用: com.aliyun.fc.runtime fc-java-core 1.3.0 通过 maven 仓库 可以获取fc-java-core最新的版本号。 在创建函数之前,用户需要将代码及其依赖的 fc-java-core 打包成 jar。关于如何打包,请参见 Java 代码打包。 打包成 jar 后就可以使用 Fun 或者控制台上传代码,以 Fun 为例: 在项目根目录创建一个 template.yml 的文件: ROSTemplateFormatVersion: '2015-09-01' Transform: 'Aliyun::Serverless-2018-04-03' Resources: FunDemo: Type: 'Aliyun::Serverless::Service' javademo: Type: 'Aliyun::Serverless::Function' Properties: Handler: example.HelloFC::handleRequest Runtime: java8 CodeUri: './example.jar' 这个 template.yml 的含义如下:声明一个名为 FunDemo 的 服务,并在这个服务下,再声明一个名为 javademo 的 函数,配置函数入口为 example.HelloFC::handleRequest,以及函数的 runtime 为 java8。并且,我们指定了 CodeUri 为 ./example.jar。在部署时,Fun 会将 CodeUri 指定的目录或文件打包上传。更多的配置规则 请参考。 示例代码包是示例中的 hello world 代码打包成的 jar 包,您可以直接使用 示例代码包 进行测试。 使用 Fun 部署: fun deploy 执行成功时,会看到相关日志: using region: cn-hangzhou using accountId: ***********3557 using accessKeyId: ***********r3Ra using timeout: 300 Waiting for service FunDemo to be deployed... Waiting for function javademo to be deployed... Waiting for packaging function javademo code... package function javademo code done function javademo deploy success service FunDemo deploy success 然后就可以登录控制台查看或直接调用了。 PojoRequestHandler 一个最简单的处理函数定义如下: // HelloFC.java package example; import com.aliyun.fc.runtime.Context; import com.aliyun.fc.runtime.PojoRequestHandler; public class HelloFC implements PojoRequestHandler<SimpleRequest, SimpleResponse> { @Override public SimpleResponse handleRequest(SimpleRequest request, Context context) { String message = "Hello, " + request.getFirstName() + " " + request.getLastName(); return new SimpleResponse(message); } } // SimpleRequest.java package example; public class SimpleRequest { String firstName; String lastName; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public SimpleRequest() {} public SimpleRequest(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } } // SimpleResponse.java package example; public class SimpleResponse { String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public SimpleResponse() {} public SimpleResponse(String message) { this.message = message; } } 准备调用的输入文件: { "firstName": "FC", "lastName": "aliyun" } 使用 fcli 调用结果: invk hello-java -f /tmp/a.json {"message":"Hello, FC aliyun"} initializer 入口 无论您的函数使用流式输入还是通过泛型的方式自定义输入和输出,当需要在 Java runtime 中添加 initializer 接口时,都需在原有的基础上额外实现 initializer 预定义的接口。 initializer预定义接口如下: package com.aliyun.fc.runtime; import java.io.IOException; public interface FunctionInitializer { /** * The interface to handle a function compute initialize request * * @param context The function compute initialize environment context object. * @throws IOException IOException during I/O handling */ void initialize(Context context) throws IOException; } 一个简单的流式输入的函数和 initializer 结合的 demo 如下: package aliyun.serverless.test.example; import com.aliyun.fc.runtime.Context; import com.aliyun.fc.runtime.FunctionComputeLogger; import com.aliyun.fc.runtime.StreamRequestHandler; import com.aliyun.fc.runtime.FunctionInitializer; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class InitializerAndStreamRequest implements StreamRequestHandler, FunctionInitializer { @Override public void initialize(Context context) { FunctionComputeLogger logger = context.getLogger(); logger.debug(String.format("RequestID is %s %n", context.getRequestId())); } @Override public void handleRequest(InputStream input, OutputStream output, Context context) throws IOException { FunctionComputeLogger logger = context.getLogger(); logger.debug(String.format("RequestID is %s %n", context.getRequestId())); output.write(new String("hello world!").getBytes()); output.flush(); } } 针对 InitializerAndStreamRequest 中新增加的 initialize 方法即是 initializer 接口,特性如下: 包名/类名 initializer 所属包名和类名和处理函数一致,都可以是任意的。”initializer” 的格式同为 {package}.{class}::{method},与 “handler” 不同的是 handler 中的 method 为 handleRequest,initializer 的 method 为 initialize。根据定义可知此示例的 initializer 为 aliyun.serverless.test.example.InitializerAndStreamRequest::initialize。 实现的接口 用户的代码中必须要实现函数计算预定义的接口。上面示例中 initializer 接口实现了FunctionInitializer,initializer 接口只有一个 context 参数。 context参数 context 参数中包含一些函数的运行时信息(例如 request id/临时 AK 等)。其类型是 com.aliyun.fc.runtime.Context。 返回值 实现FunctionInitializer接口的函数无返回结果。 泛型的方式输入的函数和 initializer 结合的 demo 如下: package aliyun.serverless.test.example; import com.aliyun.fc.runtime.Context; import com.aliyun.fc.runtime.PojoRequestHandler; import com.aliyun.fc.runtime.FunctionInitializer; import com.aliyun.fc.runtime.FunctionComputeLogger; public class InitializerAndPojoRequest implements FunctionInitializer,PojoRequestHandler<SimpleRequest, SimpleResponse> { @Override public void initialize(Context context) { FunctionComputeLogger logger = context.getLogger(); logger.debug(String.format("RequestID is %s %n", context.getRequestId())); } @Override public SimpleResponse handleRequest(SimpleRequest request, Context context) { FunctionComputeLogger logger = context.getLogger(); logger.debug(String.format("RequestID is %s %n", context.getRequestId())); String message = "Hello, " + request.getFirstName() + " " + request.getLastName(); return new SimpleResponse(message); } } HTTP 触发器函数入口 HTTP 触发器函数接口 HTTP 触发器的简单示例 HTTP 触发器支持传统web应用 关于 HTTP 触发器 的使用请参考:HTTP 触发器 HTTP 触发器函数接口 函数计算提供基于 Servlet 协议的 HTTP 触发器入口,具体接口形式如下: public interface HttpRequestHandler { /** * The entrance function of fc http trigger * @param request The servlet request * @param response The servlet response * @param context The fc context * @throws IOException If IO exception happened * @throws ServletException If servlet exception happened */ public void handleRequest(HttpServletRequest request, HttpServletResponse response, Context context) throws IOException, ServletException; } 使用 HTTP 触发器需将 fc-java-core 库版本升级到 1.3.0 及以上。 HTTP 触发器的简单示例 package com.aliyun.fc.example; import java.io.IOException; import java.io.OutputStream; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.aliyun.fc.runtime.Context; import com.aliyun.fc.runtime.HttpRequestHandler; public class Hello implements HttpRequestHandler { public void handleRequest(HttpServletRequest request, HttpServletResponse response, Context context) throws IOException, ServletException { String requestPath = (String) request.getAttribute("FC_REQUEST_PATH"); String requestURI = (String) request.getAttribute("FC_REQUEST_URI"); String requestClientIP = (String) request.getAttribute("FC_REQUEST_CLIENT_IP"); response.setStatus(200); response.setHeader("header1", "value1"); response.setHeader("header2", "value2"); String body = String.format("Path: %s\n Uri: %s\n IP: %s\n", requestPath, requestURI, requestClientIP); OutputStream out = response.getOutputStream(); out.write((body).getBytes()); out.flush(); out.close(); } } 1. HttpServletRequest 函数计算 HTTP 触发器的接口直接使用标准的 Servlet 协议。 用户的请求会封装成HttpServletRequest对象,用户请求参数、请求header等均可通过此对象获取。 除此之外,函数计算在HttpServletRequest中预封装了一些属性, 可通过 getAttribute 方法来获取, 具体包括: FC_REQUEST_PATH 获取请求的 Path FC_REQUEST_URI 获取请求的 URI FC_REQUEST_CLIENT_IP 获取请求的 ClientIP HttpServletResponse 用户可通过标准的HttpServletResponse协议对象来返回响应 header 和 body. context参数 context 参数中包含一些函数的运行时信息(例如 request id/临时 AK 等)。其类型是 com.aliyun.fc.runtime.Context。 HTTP 触发器支持传统web应用 基于 Servlet 协议的传统 web 应用能很方便的迁移到函数计算平台,目前支持的主流框架包括 Spring 、 SpringBoot 、 Struts2 等。以下示例如何通过函数计算提供的 fc-java-common 库来加载 web 应用. 打包您的 web 工程,生成 demo.war 包 上传 demo.war 包到 OSS,比如为 demo-bucket 下的 demo.war 创建函数,并设置函数初始化入口和函数入口。 函数示例代码如下: package com.aliyun.fc.example; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.aliyun.fc.runtime.Context; import com.aliyun.fc.runtime.FcAppLoader; import com.aliyun.fc.runtime.FunctionComputeLogger; import com.aliyun.fc.runtime.FunctionInitializer; import com.aliyun.fc.runtime.HttpRequestHandler; public class HelloWeb implements FunctionInitializer, HttpRequestHandler { private FcAppLoader fcAppLoader = new FcAppLoader(); private String ossEndPoint = "YourOSSEndPoint"; private String bucket = "YourOSSBucket"; private String key = "YourWarName"; private String userContextPath = "/2016-08-15/proxy/{YourServiceName}/{YourFunctionName}"; @Override public void initialize(Context context) throws IOException { FunctionComputeLogger fcLogger = context.getLogger(); fcAppLoader.setFCContext(context); // Load code from OSS fcAppLoader.loadCodeFromOSS(ossEndPoint, bucket, key); // Init webapp from code fcAppLoader.initApp(userContextPath, HelloWeb.class.getClassLoader()); } @Override public void handleRequest(HttpServletRequest request, HttpServletResponse response, Context context) throws IOException, ServletException { try { fcAppLoader.forward(request, response); } catch (Exception e) { e.printStackTrace(); } } } 引用 Maven 库 com.aliyun.fc.runtime fc-java-core 1.3.0 com.aliyun.fc.runtime fc-java-common 2.2.2 Java 代码打包 使用 maven 打包jar 使用 IDEA 打包jar 使用 maven 打包 jar 在 pom.xml 中添加 maven-assembly-plugin 插件 maven-assembly-plugin 3.1.0 jar-with-dependencies false make-assembly package single org.apache.maven.plugins maven-compiler-plugin 1.8 1.8 打包 mvn package 执行完毕后,生成的 jar 会被存放在 target 目录下。 使用 maven 打包 jar,并将依赖以 jar 的形式存放在 /lib 目录中 随着项目依赖的增加,jar 的体积会变得越来越大。而用户上传的 jar 或者 zip 代码,在执行前,首先会被解压缩,然后才会被加载、执行。因此在刚才的两种实现中,存在的一个问题是我们打包的 jar 中包含了大量的 class 文件,这无疑会增加解压缩的时间,进而增加函数的首次启动时间。 一个更好的实践是将第三方依赖以 jar 的形式,存放于 /lib 目录。 这里提供一种使用 maven-dependency-plugin 实现的方案: org.apache.maven.plugins maven-dependency-plugin copy-dependencies prepare-package copy-dependencies ${project.build.directory}/classes/lib runtime 执行完 mvn package,打包好的 jar 的目录结构为: /.class lib/*.jar 使用 IDEA 打包 jar 配置导出 jar 包的选项: java1 java2 java3 验证打包结果 rockuw-MBP:hello-java (master) $ ls -lrth total 6520 -rw-r--r-- 1 rockuw staff 3.2M Aug 31 21:03 hellofc.jar rockuw-MBP:hello-java (master) $ jar -tf hellofc.jar | head Picked up _JAVA_OPTIONS: -Duser.language=en META-INF/MANIFEST.MF example/ example/HelloFC.class example/SimpleRequest.class example/SimpleResponse.class META-INF/ META-INF// org/ org// org/apache/ 函数计算目前支持以下 Java 运行环境: OpenJDK 1.8.0 (runtime = java8) 对于 Java 运行环境的基本使用请参考Java 函数入口。以下将介绍 Java 运行环境相关特性: 使用 context 使用 logging 使用自定义的模块 异常处理 使用context context 是函数计算在运行时生成的一个对象,其中包含一些运行时的信息,用户在代码中可以使用这些信息。其定义如下,具体实现可以在 这里 找到: package com.aliyun.fc.runtime; public interface Context { public String getRequestId(); public Credentials getExecutionCredentials(); public FunctionParam getFunctionParam(); public FunctionComputeLogger getLogger(); } 可以看到 context 中包含了4个信息: RequestId: 本次调用请求的唯一 id,用户可以把它记录下来在出现问题的时候方便调查 FunctionParam: 当前调用的函数的一些基本信息如函数名/函数入口/函数内存/超时时间 ExecutionCredentials: 函数计算服务通过扮演用户提供的 服务角色获得的一组临时密钥,其有效时间是 5 分钟。用户可以在代码中使用它去访问相应的服务(例如 OSS),这就避免了用户把自己的 AK 信息写死在函数代码里。 Logger: 函数计算封装过的 logger,见下面的 使用logging 例如下面的代码使用临时密钥,向 OSS 中上传了一个文件: package example; import com.aliyun.fc.runtime.Context; import com.aliyun.fc.runtime.Credentials; import com.aliyun.fc.runtime.StreamRequestHandler; import com.aliyun.oss.OSSClient; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class HelloFC implements StreamRequestHandler { @Override public void handleRequest( InputStream inputStream, OutputStream outputStream, Context context) throws IOException { String endpoint = "oss-cn-shanghai.aliyuncs.com"; String bucketName = "my-bucket"; Credentials creds = context.getExecutionCredentials(); OSSClient client = new OSSClient( endpoint, creds.getAccessKeyId(), creds.getAccessKeySecret(), creds.getSecurityToken()); client.putObject(bucketName, "my-object", new ByteArrayInputStream(new String("hello").getBytes())); outputStream.write(new String("done").getBytes()); } } 使用logging 用户的函数通过 context.getLogger() 打印的内容会被收集到用户在创建 Service 时指定的 LogStore 中: package example; import com.aliyun.fc.runtime.Context; import com.aliyun.fc.runtime.StreamRequestHandler; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class HelloFC implements StreamRequestHandler { @Override public void handleRequest( InputStream inputStream, OutputStream outputStream, Context context) throws IOException { context.getLogger().info("hello world"); outputStream.write(new String("hello world").getBytes()); } } 上面的代码输出的日志内容是: message:2017-07-05T05:13:35.920Z a72df088-f738-cee3-e0fe-323ad89118e5 [INFO] hello world 使用 context.getLogger().warn 和 context.getLogger().error 分别可以打包 WARN/ERROR 级别的日志。 使用自定义的模块 如果用户需要使用自定义的模块,则需要在打包 jar 时,将它们与代码一起打包。以下演示如何将 OSS Java SDK 打包到项目中。 在 pom.xml 中添加 OSS java SDK: com.aliyun.fc.runtime fc-java-core 1.2.1 com.aliyun.oss aliyun-sdk-oss 2.6.1 执行通用打包流程 请参考 Java 代码打包 错误处理 用户的函数在执行过程如果抛出异常,那么函数计算会把异常捕获并将异常信息返回。例如下面的代码: package example; import com.aliyun.fc.runtime.Context; import com.aliyun.fc.runtime.StreamRequestHandler; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class HelloFC implements StreamRequestHandler { @Override public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException { throw new IOException("oops"); } } 调用时收到的响应为: invk hello-java -f /tmp/a.json { "errorMessage" : "oops", "errorType" : "java.io.IOException", "errorCause" : "oops", "stackTrace" : [ "example.HelloFC.handleRequest(HelloFC.java:15)" ] } Error: Request id: 45dd8d90-6b78-cce3-087c-8bf4ebc6c9af. Error type: UnhandledInvocationError 发生异常时,函数调用的响应的HTTP header中会包含X-Fc-Error-Type: UnhandledInvocationError。

1934890530796658 2020-03-27 16:27:27 0 浏览量 回答数 0

回答

前言 这篇文章适合所有的 C# 开发新手、老鸟以及想准备学习开发 C# 的程序猿。.NET Core是一个开源通用的开发框架,支持跨平台, 阿里云函数计算推出了 dotnetcore2.1 runtime, 使用 C# 编写 serverless 函数, 详情见官方文档:C# 函数入口. 在官方文档描述中,我们获知阿里云函数计算可以很好支持 asp.net core 的 Applicaiton: ASP.NET Core Web API ASP.NET Core Web App ASP.NET Core Web App (Model-View-Controller) 在介绍 Serverless Web 开发新模式之前,我们先了解下将 C# WebApi/WebApp Serverless 化的好处: 无需采购和管理服务器等基础设施 弹性伸缩,动态扩容 免运维, 极大降低人力成本 按需付费,财务成本低 本文以部署一个完善的 asp.net core 工程 Blogifier 为例,在函数计算环境中为例,向您讲解如何使用阿里云函数计算快速构建或移植基于 asp.net core 开发的 WebApi/WebApp ,通过本文,您将会了解以下内容: 案例概览 传统服务器架构 VS Serverless架构 Serverless架构详解 函数计算运行 Asp.net core App 原理 案例开发配置步骤 案例概览 在本教程中,我们讲解如何利用函数计算一步一步来构建 Web 的 Server 端,该案例是把一个 asp.net core 工程Blogifier 部署到函数计算,本文旨在展示函数计算做 Web Backend 能力,具体表现为以下几点: 完善的 ASP.NET Core Web 系统迁移到 FC 的成本不高 FC 打通了专有网络 VPC 功能,用户的函数可以配置访问专有网络的云资源,比如本案例中 NAS 案例体验入口: http://dotnet.mofangdegisn.cn/ https://dotnet.mofangdegisn.cn/ 传统服务器架构 VS Serverless架构 正常来说,用户开发 Server 端服务,常常面临开发效率,运维成本高,机器资源弹性伸缩等痛点,而使用 Serverless 架构可以很好的解决上述问题。下面是传统架构和 Serverless 架构的对比: image 阿里云函数计算是一个事件驱动的全托管计算服务。通过函数计算,您无需管理服务器等基础设施,只需编写代码并上传。函数计算会为您准备好计算资源,以弹性、可靠的方式运行您的代码,并提供日志查询,性能监控,报警等功能。借助于函数计算,您可以快速构建任何类型的应用和服务,无需管理和运维。 Serverless 架构详解 image.png 从上面的示例图中,整体架构十分简单明了, 用 FC 替代了 Web 服务器,但是换来的是免运维,弹性扩容,按需付费等一系列优点 函数计算运行 Asp.net Core App 原理 Asp.net Core App 运行在服务器上 image A http request to your website will go through IIS/Nginx, then Kestrel, and finally will be passed on to ASP.NET Core Asp.net Core App 运行在函数计算上 image 请求通过函数(with http trigger), 最后到达ASP.NET Core tips: 基于函数计算环境运行新建 asp.net core app 可以参考dotnet runtime HTTP 触发器的函数入口示例 在本文中,我们展示把一个现有的成熟的 asp.net core 工程低成本无缝迁移到函数计算环境。 案例开发配置步骤 准备工作 1. 创建 NAS 挂接点,配置 VPC , 具体参考函数计算nas使用示例 注:在本示例中使用 sqlite3 数据库,这种文件类型的数据库直接放置在 nas 即可,如果使用 mysql 等其他数据库, 需要创建 RDS 数据库, 配置 VPC , 具体参考通过 VPC 访问 RDS 实例 可选操作,在准备函数的 region 创建日志,用于函数的调试, 具体参考函数计算配置日志服务 创建函数 创建 Service (假设是 csharp-web), 配置准备 vpc config , nas config 和日志服务,比如案例体验的 Service 配置如下图: image 下载 asp.net core 工程,Blogifier, 用 vs 打开, debug 本地可以正常运行。 注:本地安装 dotnetcore2.1 在工程中增加入口函数,使得该工程可在函数计算执行环境运行,diff dotnet publish -c Release, 跳转到publish目录, 将相关的静态资源/可写/共享目录移动到上述配置的 NAS 的某个目录(这里假设是 www目录, 对应步骤2中的diff) dotnet publish -c Release cp -r plugins/Common/bin/Release/netcoreapp2.1/publish/* src/App/bin/Release/netcoreapp2.1/publish/ src/App/bin/Release/netcoreapp2.1/publish/ mkdir lib // 选择函数计算执行环境所需要的so, 其他的删除即可 cp runtimes/linux-x64/native/libe_sqlite3.so ./lib // 这里是传送对应的静态文件和 app.db 到 nas 中, 详情看下面的描述 rm -rf wwwroot app.db runtimes zip -r code.zip * // 最后使用这个 code.zip 创建 handler 为 App::App.FcRemoteEntrypoint::HandleRequest 函数 将 publish 目录下的 wwwroot 和 app.db 传送到 nas 的 www 目录, 可以使用 ecs 挂载 nas 传输过去, 也可以采用如下简单函数传输过去 |-- index.py |-- www 注: www目录下面有 wwwroot 和 app.db index.py代码: -- coding: utf-8 -- import logging import os def handler(event, context): os.system("mkdir -p /mnt/share/www") os.system("cp -r /code/www/* /mnt/share/www/") os.system("chmod -R 777 /mnt/share/www") print( os.system("ls -ll /mnt/share/www") ) return 'ok' 基于上述代码创一个函数 move-res-nas , 执行函数,将相关静态和共享资源移动到 NAS 的/mnt/share/www/ 目录。 注:最新版本的 Fun 工具已经支持 NAS 相关操作, 有兴趣的同学可以使用 Fun 完成 NAS, VPC 的自动生成、配置以及网站工程文件上传到 NAS 创建入口函数 blog (使用上一步骤中的 code.zip ), 给函数设置 http trigger ,类型为 anonymous , 类型都选上。给函数入口配置自定义域名(操作过程请参考:绑定自定义域名示例), 具体配置假设如下: image 注意: 绑定自定义域名之后,不用使用控制台来进行调试,就只能使用浏览器来触发函数,日志服务来进行调试。 总结 函数计算有如下优势: 无需采购和管理服务器等基础设施 专注业务逻辑的开发 提供日志查询、性能监控、报警等功能快速排查故障 以事件驱动的方式触发应用响应用户请求 毫秒级别弹性伸缩,快速实现底层扩容以应对峰值压力 按需付费。只需为实际使用的计算资源付费,适合有明显波峰波谷的用户访问场景 除了上面所列的优势,FC 可以做为 Web Backend,只需要编写一个函数实现传统 Web 服务器中的 conf 中的逻辑,就可以将一个完整的 Web 工程迁移到 FC ,从而从传统的 Web 网站运维,监控等繁琐的事务中解放出来。

1934890530796658 2020-03-27 17:30:59 0 浏览量 回答数 0

回答

前言 本文旨在通过 快速部署一个 wordpress 网站到阿里云 函数计算 平台 这个示例来展示 serverless web 新的开发模式, 包括 FUN 工具一键初始化 NAS, 同步网站到 NAS, 一键部署等能力, 展现函数计算的开发敏捷特性、自动弹性伸缩能力、免运维和完善的监控设施。 相关参考文档: https://yq.aliyun.com/articles/640912 1.1 DEMO 概述 DEMO 示例效果入口: http://hz.mofangdegisn.cn 账号: fc-test-user 密码: fc-test-pwd DEMO 示例工程地址: fc-wordpress 开通服务 免费开通函数计算, 按量付费,函数计算有很大的免费额度。 免费开通文件存储服务NAS, 按量付费 1.2 解决方案 image 如上图所示, 当多个用户通过对外提供的 url 访问web服务的时候,每秒的请求几百上千都没有关系, 函数计算平台会自动伸缩, 提供足够的执行实例来响应用户的请求, 同时函数计算提供了完善的监控设施来监控您的函数运行情况。 1.3 Serverless 方案与传统自建 web 方案对比 ITEM 成本 稳定性 基于 VM 方案 使用 ecs.t5-lc1m1.small, 22.8元/月 服务器和数据库在同一台VM, 均无主备容灾,同时该规格的主机本身性能弱 轻量应用服务器 60元/月(1vCPU 1GB 1Mbps 20GB[ssd]) 服务器和数据库在同一台VM, 均无主备容灾,同时该规格的主机本身性能弱 函数计算 sqlite3 版本约为 1元/月 mysql 版本大约 26元/月 高 函数计算完整费用详情: 每月前 100 万次函数调用免费, 每月前 400000(GB*秒) 费用免费, 函数的内存可以设置为 128M 或者 256M, 因此对于一个一个月访问量低于 100 万次的网站, 该项是免费的 对于低成本的网站, 假设一个月的产生的公网流量为 1GB, 0.8元 NAS, US$0.06/GB/Month, 网站大小为 50M, 即使按 1G 计算, 0.42元 RDS mysql 最基本的单机版本, 25元/月 函数计算计费 | NAS 定价 如上所述, 在低成本网站领域, 函数计算具有十分明显的成本优势,同时还保持了弹性能力,以后业务规模做大以后并没有技术切换成本(可能需要做的只是更换一个更强的关系型数据库), 同时财务成本增长配合预付费也能保持平滑。低成本网站变成高可用高性能网站如丝般顺滑, 高性能网站详情可以参考文末 FAQ 中的 Q1 问题。 函数计算运行 PHP 框架原理 在具体操作部署之前, 先简单梳理一遍函数计算运行 PHP 框架原理 2.1 传统服务器 PHP 运行原理 原理示意图image.png A simple nginx confimage.png 从上面原理示意图我们可以看出,Web 服务器根据 conf 中 location将 PHP 脚本交给 php-fpm 去解析,然后将解析后的结果返回给 client 端 2.2 FC 驱动 PHP 工程原理 image 函数计算的执行环境实例相当于传统 web 服务的 Apache/Nginx 用户函数相当于实现 Apache/Nginx 的 conf 中 location 用户将 Web 网站部署在 NAS,然后挂载 NAS 到函数的执行环境, 比如下面代码中 /mnt/auto 目录 对于 WordPress 入口函数代码就是这么简单: index.php 其中函数计算为用户提供了一个 $GLOBALS['fcPhpCgiProxy'] 对象用来和 php-fpm 进行交互,对PHP 工程中的 php 文件进行解析,该对象提供了两个重要的接口: requestPhpCgi requestPhpCgi($request, $docRoot, $phpFile = "index.php", $fastCgiParams = [], $options = []) $request: 跟 php http invoke 入口的参数一致 $docRoot: Web 工程的根目录 $phpFile: 用于拼接 cgi 参数中的 SCRIPT_FILENAME 的默认参数 $fastCgiParams: 函数计算内部尽量根据 $request给您构造 default cgi params, 但是如果您不是想要的,可以使用$fastCgiParams覆盖一些参数 (reference: cgi) $options: array类型,可选参数, debug_show_cgi_params 设为 true ,会打印每次请求 php 解析时候的 cgi 参数, 默认为 false ;readWriteTimeout 设置解析的时间, 默认为 5 秒 如果您有兴趣, 可以了解下函数计算 PHP Runtime: PHP 入口函数 PHP 执行环境 案例操作步骤 准备条件 免费开通函数计算, 按量付费,函数计算有很大的免费额度。 免费开通文件存储服务NAS, 按量付费 有一个域名, 比如 abc.com, 并将域名 CNAME 解析到函数计算(FC) 对应的 region 如您想在杭州的 region 部署 wordpres 网站, 则将 abc.com CNAME 解析到 12345.cn-hangzhou.fc.aliyuncs.com, 其中 12345 是您的 accountId 3.1 安装最新的 Fun 工具 安装版本为8.x 最新版或者10.x 、12.x nodejs 安装 funcraf 3.2 Clone 工程 git clone https://github.com/awesome-fc/fc-wordpress.git 3.3 根据需要使用的数据库进入不同的目录 复制 .env_example 文件为 .env, 并且修改 .env 中的信息为自己的信息 如果使用 mysql 数据库, 参考章节 3.3.1 如果使用 sqlite3 数据库, 参考章节 3.3.2 3.3.1 使用 mysql 数据库 进入目录 fc-wp-mysql fun nas init fun nas info fun nas init: 初始化 NAS, 基于您的 .env 中的信息获取(已有满足条件的nas)或创建一个同region可用的nas 如果你没有修改 templata.yml 中的配置 service名字, 那么则可以进入下一步; 如果有修改, 会在当前目录生成新的目录 .fun/nas/auto-default/{serviceName} (fun nas info 可以列出新的目录), 将默认目录下的 .fun/nas/auto-default/fc-wp-mysql/wordpress 的wordpress目录拷贝到 .fun/nas/auto-default/{serviceName} 下, 同时可以删除目录 .fun/nas/auto-default/fc-wp-mysql/wordpress 上传 wordpress 网站到 NAS fun nas sync fun nas ls nas:///mnt/auto/ fun nas sync: 将本地 NAS 中的内容(.fun/nas/auto-default/fc-wp-mysql)上传到 NAS 中的 fc-wp-mysql 目录 fun nas ls nas:///mnt/auto/: 查看我们是否已经正确将文件上传到了 NAS 3.3.2 使用 sqlite3 数据库 进入目录 fc-wp-sqlite fun nas init fun nas info fun nas init: 初始化 NAS, 基于您的 .env 中的信息获取(已有满足条件的nas)或创建一个同region可用的nas 如果你没有修改 templata.yml 中的配置 service名字, 那么则可以进入下一步; 如果有修改, 会在当前目录生成新的目录 .fun/nas/auto-default/{serviceName} (fun nas info 可以列出新的目录), 将默认目录下的 .fun/nas/auto-default/fc-wp-sqlite/wordpress 的wordpress目录拷贝到 .fun/nas/auto-default/{serviceName} 下, 同时可以删除目录 .fun/nas/auto-default/fc-wp-sqlite/wordpress 本地完成安装过程, 初始化 sqlite3 数据库 在目录 .fun/nas/auto-default/fc-wp-sqlite/wordpress 中输入命令: php -S 0.0.0.0:80 修改 host 文件,添加 127.0.0.1 hz.mofangdegisn.cn linux/mac : vim /etc/hosts windows7: C:\Windows\System32\drivers\etc 其中 hz.mofangdegisn.cn 是您预先准备的域名 通过浏览器输入 hz.mofangdegisn.cn, 这个时候没有mysql数据库设置页面,完成 wordpress 安装过程 成功安装以后, 这个时候, .fun/nas/auto-default/fc-wp-sqlite/wordpress/wp-content 下面应该有一个 database 的目录, ls -a 查看, 应该有 .ht.sqlite 这个 sqlite3 数据库文件 回退 host 文件的修改 注: 中间修改 host 的目的是初始化 sqlite3 数据库的时候, base site url 是提前准备的域名, 而不是 127.0.0.1 上传 wordpress 网站到 NAS fun nas sync fun nas ls nas:///mnt/auto/ fun nas sync: 将本地 NAS 中的内容(.fun/nas/auto-default/fc-wp-sqlite)上传到 NAS 中的 fc-wp-sqlite 目录 fun nas ls nas:///mnt/auto/: 查看我们是否已经正确将文件上传到了 NAS 3.4 部署函数到FC平台 接下来将函数部署到云平台: 修改 index.php 中的 $host 中的值 修改 template.yml LogConfig 中的 Project, 任意取一个不会重复的名字即可 修改 template.yml 自定义域名为自己提前准备好的域名 执行 fun deploy 登录控制台 https://fc.console.aliyun.com,可以看到service 和函数已经创建成功, 并且 service 也已经正确配置。 通过浏览器打开自己之前配置的域名, 比如本例中的 hz.mofangdegisn.cn mysql 版本数据库, 可以直接跟传统的 wordpress 一样,直接进入安装过程 sqlite3 版本数据库, 由于之前已经完成初始化,可以直接进入网站首页或网站后台 FAQ Q1: 函数计算能开发高性能高可用网站吗? A: 可以, 使用函数计算的单实例多并发功能和高性能数据库 单实例多并发 选择高性能关系型数据库,比如高可用的云数据库PolarDB 有必要再加上这些优化: 预留实例消除冷启动 + 预付费优化成本 极速型 NAS OSS 对象存储 + CDN 来存储和分发静态资源 目前 PHP Runtime 并不支持单实例多并发, 使用 Custom Runtime,可以将基于传统模式 nginx + php-fpm + mysql 开发的网站直接简单无缝迁移到函数计算平台,示例工程 customruntime-php 使用OSS对Wordpress进行图片动静分离 Q2: 使用低成本 sqlite3 版本的网站, 冷启动第一次打开很慢怎么办? A: 用一个 timer trigger 的函数 keep warm Q3: 使用低成本 sqlite3 版本的网站, 能支持多大的qps? A: 由 sqlite3 数据库性能决定, 这边有一些压测结果: image image 每次压力增大时候, 都有些冷启动,时间慢点,但是支持从压测结果来看支持 50 QPS 是没有疑问的, 是足够支持一些中小网站的。 Q4: 使用其他语言基于函数计算开发 serverless 网站可以吗? A: 可以, 比如 python: https://yq.aliyun.com/articles/603249 , 或者直接使用 custom runtime, 内置了 java、python 和 node, Custom Runtime 用户手册 , Custom Runtime 使用集锦

1934890530796658 2020-03-27 17:54:50 0 浏览量 回答数 0

回答

Q: 函数计算 php runtime 是什么? A: 请参考官方文档: php 函数入口 php 运行环境 Q: 函数计算 php runtime 支持 http trigger 吗? A: 支持, 详情见 php HTTP 触发器的函数入口 Q: php runtime 能使用第三方扩展吗? A: 能 php 自定义扩展 php runtime 动态加载卸载内置扩展 Q: php runtime 内置的table store php sdk 使用有问题 A: 原因是内置protobuf扩展和table store 依赖的php 实现的protobuf有冲突,具体解法请参考:php runtime 动态加载卸载内置扩展;同时,针对php runtime 动态加载卸载内置扩展这个话题,鼓励用户使用环境变量来裁剪不必要的扩展来优化runtime的启动速度 Q: php runtime 对异常处理严格,比如级别较低的notice就会抛出异常,导致某些第三方库(aliyun-openapi-php-sdk)不能使用怎么办? A: 有解法,详情请参考:函数计算PHP Runtime - exception 处理 Q: php runtime 能驱动php 框架吗? A: 能,请参考 十分钟上线-函数计算玩转 WordPress 十分钟上线-函数计算&Laravel的那些事儿 用阿里云函数计算部署thinkphp5.1 云计算的1024种玩法- 1小时用阿里云函数计算部署一个 ServerLess 化的按量版 WordPress Q: 使用php runtime http trigger出现Cannot modify header information - headers already sent by (output started at ... 怎么处理? A:php runtime 中 headers already sent 问题解决方案 Q: 使用php runtime http trigger想更改 session 目录怎么处理? A:php runtime 中 headers already sent 问题解决方案 更改session 目录部分 Q: php runtime开发web时, 怎么支持rewrite? A:php runtime 中 http web 中 rewrite 浅解和方案 Q: php runtime 除了内置的扩展,想使用 php-gd 等其他php扩展怎么办? A: 函数计算 php runtime 编译非内置的扩展 Q: php runtime 两个php 文件简单require_once使用sample a.php <?php $appcode = 123456; class Foo { public $name = 'FooClass'; function sayhi() { print 'Foo say hello!'; } } $foo = new Foo; b.php <?php require_once __DIR__ . '/a.php'; function handler($event, $context) { echo $GLOBALS['appcode'] . PHP_EOL; $GLOBALS['foo']->sayhi(); $foo2 = new Foo; $foo2->sayhi(); return $GLOBALS['appcode']; }

保持可爱mmm 2020-04-15 23:05:53 0 浏览量 回答数 0

问题

SSH面试题

琴瑟 2019-12-01 21:46:22 3489 浏览量 回答数 0

回答

背景 目前有很多 web 应用是基于 express 框架写的,这样的 web 应用按照传统的部署方式可能部署在云主机上,用户可能不想购买云主机,也不想在运维上投入太多成本,函数计算是一个不错的选择,函数计算的入口方法如何适配 express 是一个相当复杂的问题,我们需要适配 http 触发器和 API 网关这两种类型的触发,但是这两种类型的函数方法签名是不一样的,我们需要分别做适配,比如 API 网关方式触发函数,需要把 event 映射到 express 的 request 对象上,而 express 的 response 对象需要映射到 callback 的数据参数上。具体细节可以参考另一篇文章:移植 express.js 应用到函数计算。 现在,我们提供了一个模板,通过该模板,可以快速将 express 项目接入函数计算,不管你的函数希望通过 http 触发器,还是 API 网关触发。并且,该模板还支持 es6 代码编译成 es5,并且剪切打包压缩成一个 js 文件。 快速开始 安装 node curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.5/install.sh | bash nvm install 8 安装 fun 工具 npm install @alicloud/fun -g fun 工具的某些子命令可能会用到 docker,所以你需要安装好 docker,具体参考文档:Fun 安装教程。 通过 fun 模板生成项目 fun init -n demo https://github.com/muxiangqiu/fc-express-nodejs8.git 项目生成好后,在根目录下有个 README.md 文件,阅读该文件可以帮你快速了解项目骨架为你做了什么,以及相关的命令。具体详情:README.md。 安装依赖 cd demo # 切换到项目根下面,后面的所有命令,都是在项目根下面执行 npm install 注意:有少数特殊 npm 模块的安装可能会依赖当前系统环境,为了能正确安装函数运行时的系统环境的 npm 模块,可以通过 fun install 命令来实现,比如 puppeteer,具体参考:开发函数计算的正确姿势 —— 安装第三方依赖。 编译 生产编译 npm run build 开发编译(这种编译方式不会进行代码混淆,并且生成 source map 信息,方便开发调试) npm run dev 本地运行函数 fun local start 运行调试函数 运行调试之前,请先用 npm run dev 命令编译源码,然后以调试的方式运行函数: fun local start -d 3000 如下图所示:debug_fc_http 部署函数到云端 部署函数的时候需要用到 AK 等下信息,可以通过 fun config 来配置,如果配置过请忽略,部署函数命令如下: fun deploy 小结 通过该模板,我们可以快速让 express 在函数计算上运行起来,你的原生请求的 headers 或者 body 都会透传给你的 express 应用,你不用关心是如何透传过去的,这些对你来说都是透明的,你只需要按照 express 标准方式写你的业务代码即可。如果你想要了解更多底层实现原理,可以参考另一篇文章:移植 express.js 应用到函数计算。

1934890530796658 2020-03-27 17:34:49 0 浏览量 回答数 0

问题

【技术干货】原来阿里云自助实验室的系统架构是这样的啊

驻云科技 2019-12-01 21:07:14 9011 浏览量 回答数 1

回答

一 系统介绍 Android 是Google开发的基于Linux平台的、开源的、智能手机操作系统。Android包括操作系统、中间件和应用程序,由于源代码开放,Android可以被移植到不同的硬件平台上。 围绕在Google的Android系统中,形成了移植开发和上层应用程序开发两个不同的开发方面。手机厂商从事移植开发工作,上层的应用程序开发可以由任何单位和个人完成,开发的过程可以基于真实的硬件系统,还可以基于仿真器环境。 作为一个手机平台,Android在技术上的优势主要有以下几点: - 全开放智能手机平台 - 多硬件平台的支持 - 使用众多的标准化技术 - 核心技术完整,统一 - 完善的SDK和文档 - 完善的辅助开发工具 Android的开发者可以在完备的开发环境中进行开发,Android的官方网站也提供了丰富的文档、资料。这样有利于Android系统的开发和运行在一个良好的生态环境中。 https://developer.android.com/about安卓开发者官方网站 从宏观的角度来看,Android是一个开放的软件系统,它包含了众多的源代码。从下至上,Android系统分成4个层次: 第1层次:Linux操作系统及驱动; 第2层次:本地代码(C/C++)框架; 第3层次:Java框架; 第4层次:Java应用程序。 Android系统的架构如图所示: 由于Android系统需要支持Java代码的运行,这部分内容是Android的运行环境(Runtime),由虚拟机和Java基本类组成。 对于Android应用程序的开发,主要关注第3层次和第4层次之间的接口。 二 学习路线 基础学习——JavaSE: 基础学习扩展——JavaEE: 基础学习扩展——Linux基础: Android开发学习——基础理论:系统架构分析: Android系统从底向上一共分了4层,每一层都把底层实现封装,并暴露调用接口给上一层。 Linux内核(Linux Kernel) Android运行在linux kernel 2.6之上,但是把linux内受GNU协议约束的部分做了取代,这样在Android的程序可以用于商业目的。 Linux 内核是硬件和软件层之间的抽象层。 中间件 中间件包括两部分: 核心库和运行时(libraries & Android runtime) 核心库包括,SurfaceManager 显示系统管理库,负责把2D或3D内容显示到屏幕;Media Framework 媒体库,负责支持图像,支持多种视频和音频的录制和回放;SQlite 数据库,一个功能强大的轻量级嵌入式关系数据库;WebKit 浏览器引擎等。 Dalvik虚拟机: 区别于Java虚拟机的是,每一个Android 应用程序都在它自己的进程中运行,都有一个属于自己的Dalvik 虚拟机,这一点可以让系统在运行时可以达到优化,程序间的影响大大降低。Dalvik虚拟机并非运行Java字节码,而是运行自己的字节码。 应用程序框架(Application Framework) 丰富而又可扩展性的视图(Views),可以用来构建应用程序, 它包括列表(lists),网格(grids), 文本框(text boxes),按钮( buttons), 可嵌入的web 浏览器。内容提供者(Content Providers)使得应用程序可以访问另一个应用程序的数据(如联系人数据库), 或者共享它们自己的数据。资源管理器(Resource Manager)提供非代码资源的访问,如本地字符串,图形,和布局文件( layoutfiles )。通知管理器(Notification Manager) 使得应用程序可以在状态栏中显示自定义的提示信息。活动管理器( Activity Manager) 用来管理应用程序生命周期并提供常用的导航回退功能。 三 基础知识 掌握java部分之后,可以使用开发工具进入android世界 您可以使用 Kotlin、Java 和 C++ 语言编写 Android 应用。Android SDK 工具会将您的代码连同任何数据和资源文件编译成一个 APK(Android 软件包),即带有 .apk 后缀的归档文件。一个 APK 文件包含 Android 应用的所有内容,它也是 Android 设备用来安装应用的文件。 每个 Android 应用都处于各自的安全沙盒中,并受以下 Android 安全功能的保护: • Android 操作系统是一种多用户 Linux 系统,其中的每个应用都是一个不同的用户; • 默认情况下,系统会为每个应用分配一个唯一的 Linux 用户 ID(该 ID 仅由系统使用,应用并不知晓)。系统会为应用中的所有文件设置权限,使得只有分配给该应用的用户 ID 才能访问这些文件; • 每个进程都拥有自己的虚拟机 (VM),因此应用代码独立于其他应用而运行。 • 默认情况下,每个应用都在其自己的 Linux 进程内运行。Android 系统会在需要执行任何应用组件时启动该进程,然后当不再需要该进程或系统必须为其他应用恢复内存时,其便会关闭该进程。 Android 系统实现了最小权限原则。换言之,默认情况下,每个应用只能访问执行其工作所需的组件,而不能访问其他组件。这样便能创建非常安全的环境,在此环境中,应用无法访问其未获得权限的系统部分。不过,应用仍可通过一些途径与其他应用共享数据以及访问系统服务: • 可以安排两个应用共享同一 Linux 用户 ID,在此情况下,二者便能访问彼此的文件。为节省系统资源,也可安排拥有相同用户 ID 的应用在同一 Linux 进程中运行,并共享同一 VM。应用还必须使用相同的证书进行签名。 • 应用可以请求访问设备数据(如用户的联系人、短信消息、可装载存储装置(SD 卡)、相机、蓝牙等)的权限。用户必须明确授予这些权限。如需了解详细信息,请参阅使用系统权限。 本文档的其余部分将介绍以下概念: • 用于定义应用的核心框架组件 • 用来声明组件和应用必需设备功能的清单文件。 • 与应用代码分离并允许应用针对各种设备配置适当优化其行为的资源。 应用组件 应用组件是 Android 应用的基本构建块。每个组件都是一个入口点,系统或用户可通过该入口点进入您的应用。有些组件会依赖于其他组件。 共有四种不同的应用组件类型: • Activity • 服务 • 广播接收器 • 内容提供程序 每种类型都有不同的用途和生命周期,后者会定义如何创建和销毁组件。以下部分将介绍应用组件的四种类型。 Activity Activity 是与用户交互的入口点。它表示拥有界面的单个屏幕。例如,电子邮件应用可能有一个显示新电子邮件列表的 Activity、一个用于撰写电子邮件的 Activity 以及一个用于阅读电子邮件的 Activity。尽管这些 Activity 通过协作在电子邮件应用中形成一种紧密结合的用户体验,但每个 Activity 都独立于其他 Activity 而存在。因此,其他应用可以启动其中任何一个 Activity(如果电子邮件应用允许)。例如,相机应用可以启动电子邮件应用内用于撰写新电子邮件的 Activity,以便用户共享图片。Activity 有助于完成系统和应用程序之间的以下重要交互: • 追踪用户当前关心的内容(屏幕上显示的内容),以确保系统继续运行托管 Activity 的进程。 • 了解先前使用的进程包含用户可能返回的内容(已停止的 Activity),从而更优先保留这些进程。 • 帮助应用处理终止其进程的情况,以便用户可以返回已恢复其先前状态的 Activity。 • 提供一种途径,让应用实现彼此之间的用户流,并让系统协调这些用户流。(此处最经典的示例是共享。) 您需将 Activity 作为 Activity 类的子类来实现。如需了解有关 Activity 类的更多信息,请参阅 Activity 开发者指南。 服务 服务是一个通用入口点,用于因各种原因使应用在后台保持运行状态。它是一种在后台运行的组件,用于执行长时间运行的操作或为远程进程执行作业。服务不提供界面。例如,当用户使用其他应用时,服务可能会在后台播放音乐或通过网络获取数据,但这不会阻断用户与 Activity 的交互。诸如 Activity 等其他组件可以启动服务,使该服务运行或绑定到该服务,以便与其进行交互。事实上,有两种截然不同的语义服务可以告知系统如何管理应用:已启动服务会告知系统使其运行至工作完毕。此类工作可以是在后台同步一些数据,或者在用户离开应用后继续播放音乐。在后台同步数据或播放音乐也代表了两种不同类型的已启动服务,而这些服务可以修改系统处理它们的方式: • 音乐播放是用户可直接感知的服务,因此,应用会向用户发送通知,表明其希望成为前台,从而告诉系统此消息;在此情况下,系统明白它应尽全力维持该服务进程运行,因为进程消失会令用户感到不快。 • 通常,用户不会意识到常规后台服务正处于运行状态,因此系统可以更自由地管理其进程。如果系统需要使用 RAM 来处理用户更迫切关注的内容,则其可能允许终止服务(然后在稍后的某个时刻重启服务)。 绑定服务之所以能运行,原因是某些其他应用(或系统)已表示希望使用该服务。从根本上讲,这是为另一个进程提供 API 的服务。因此,系统会知晓这些进程之间存在依赖关系,所以如果进程 A 绑定到进程 B 中的服务,系统便知道自己需使进程 B(及其服务)为进程 A 保持运行状态。此外,如果进程 A 是用户关心的内容,系统随即也知道将进程 B 视为用户关心的内容。由于存在灵活性(无论好坏),服务已成为非常有用的构建块,并且可实现各种高级系统概念。动态壁纸、通知侦听器、屏幕保护程序、输入方法、无障碍功能服务以及众多其他核心系统功能均可构建为在其运行时由应用实现、系统绑定的服务。 您需将服务作为 Service 的子类来实现。如需了解有关 Service 类的更多信息,请参阅服务开发者指南。 注意:如果您的应用面向 Android 5.0(API 级别 21)或更高版本,请使用 JobScheduler 类来调度操作。JobScheduler 的优势在于,它能通过优化作业调度来降低功耗,以及使用 Doze API,从而达到省电目的。如需了解有关使用此类的更多信息,请参阅 JobScheduler 参考文档。 广播接收器 借助广播接收器组件,系统能够在常规用户流之外向应用传递事件,从而允许应用响应系统范围内的广播通知。由于广播接收器是另一个明确定义的应用入口,因此系统甚至可以向当前未运行的应用传递广播。例如,应用可通过调度提醒来发布通知,以告知用户即将发生的事件。而且,通过将该提醒传递给应用的广播接收器,应用在提醒响起之前即无需继续运行。 许多广播均由系统发起,例如,通知屏幕已关闭、电池电量不足或已拍摄照片的广播。应用也可发起广播,例如,通知其他应用某些数据已下载至设备,并且可供其使用。尽管广播接收器不会显示界面,但其可以创建状态栏通知,在发生广播事件时提醒用户。但广播接收器更常见的用途只是作为通向其他组件的通道,旨在执行极少量的工作。例如,它可能会根据带 JobScheduler 的事件调度 JobService 来执行某项工作 广播接收器作为 BroadcastReceiver 的子类实现,并且每条广播都作为 Intent 对象进行传递。如需了解详细信息,请参阅 BroadcastReceiver 类。 内容提供程序 内容提供程序管理一组共享的应用数据,您可以将这些数据存储在文件系统、SQLite 数据库、网络中或者您的应用可访问的任何其他持久化存储位置。其他应用可通过内容提供程序查询或修改数据(如果内容提供程序允许)。例如,Android 系统可提供管理用户联系人信息的内容提供程序。 因此,任何拥有适当权限的应用均可查询内容提供程序(如 ContactsContract.Data),以读取和写入特定人员的相关信息。我们很容易将内容提供程序看作数据库上的抽象,因为其内置的大量 API 和支持时常适用于这一情况。但从系统设计的角度看,二者的核心目的不同。对系统而言,内容提供程序是应用的入口点,用于发布由 URI 架构识别的已命名数据项。因此,应用可以决定如何将其包含的数据映射到 URI 命名空间,进而将这些 URI 分发给其他实体。反之,这些实体也可使用分发的 URI 来访问数据。在管理应用的过程中,系统可以执行以下特殊操作: • 分配 URI 无需应用保持运行状态,因此 URI 可在其所属的应用退出后继续保留。当系统必须从相应的 URI 检索应用数据时,系统只需确保所属应用仍处于运行状态。 • 这些 URI 还会提供重要的细粒度安全模型。例如,应用可将其所拥有图像的 URI 放到剪贴板上,但将其内容提供程序锁定,以便其他应用程序无法随意访问它。当第二个应用尝试访问剪贴板上的 URI 时,系统可允许该应用通过临时的 URI 授权来访问数据,这样便只能访问 URI 后面的数据,而非第二个应用中的其他任何内容。 内容提供程序也适用于读取和写入您的应用不共享的私有数据。 内容提供程序作为 ContentProvider 的子类实现,并且其必须实现一组标准 API,以便其他应用能够执行事务。如需了解详细信息,请参阅内容提供程序开发者指南。 Android 系统设计的独特之处在于,任何应用都可启动其他应用的组件。例如,当您想让用户使用设备相机拍摄照片时,另一个应用可能也可执行该操作,因而您的应用便可使用该应用,而非自行产生一个 Activity 来拍摄照片。您无需加入甚至链接到该相机应用的代码。只需启动拍摄照片的相机应用中的 Activity 即可。完成拍摄时,系统甚至会将照片返回您的应用,以便您使用。对用户而言,这就如同相机是您应用的一部分。 当系统启动某个组件时,它会启动该应用的进程(如果尚未运行),并实例化该组件所需的类。例如,如果您的应用启动相机应用中拍摄照片的 Activity,则该 Activity 会在属于相机应用的进程(而非您的应用进程)中运行。因此,与大多数其他系统上的应用不同,Android 应用并没有单个入口点(即没有 main() 函数)。 由于系统在单独的进程中运行每个应用,且其文件权限会限制对其他应用的访问,因此您的应用无法直接启动其他应用中的组件,但 Android 系统可以。如要启动其他应用中的组件,请向系统传递一条消息,说明启动特定组件的 Intent。系统随后便会为您启动该组件。 启动组件 在四种组件类型中,有三种(Activity、服务和广播接收器)均通过异步消息 Intent 进行启动。Intent 会在运行时对各个组件进行互相绑定。您可以将 Intent 视为从其他组件(无论该组件是属于您的应用还是其他应用)请求操作的信使。 您需使用 Intent 对象创建 Intent,该对象通过定义消息来启动特定组件(显式 Intent)或特定的组件类型(隐式 Intent)。 对于 Activity 和服务,Intent 会定义要执行的操作(例如,查看或发送某内容),并且可指定待操作数据的 URI,以及正在启动的组件可能需要了解的信息。例如,Intent 可能会传达对 Activity 的请求,以便显示图像或打开网页。在某些情况下,您可以通过启动 Activity 来接收结果,这样 Activity 还会返回 Intent 中的结果。例如,您可以发出一个 Intent,让用户选取某位联系人并将其返回给您。返回 Intent 包含指向所选联系人的 URI。 对于广播接收器,Intent 只会定义待广播的通知。例如,指示设备电池电量不足的广播只包含指示“电池电量不足”的已知操作字符串。 与 Activity、服务和广播接收器不同,内容提供程序并非由 Intent 启动。相反,它们会在成为 ContentResolver 的请求目标时启动。内容解析程序会通过内容提供程序处理所有直接事务,因此通过提供程序执行事务的组件便无需执行事务,而是改为在 ContentResolver 对象上调用方法。这会在内容提供程序与请求信息的组件之间留出一个抽象层(以确保安全)。 每种组件都有不同的启动方法: • 如要启动 Activity,您可以向 startActivity() 或 startActivityForResult() 传递 Intent(当您想让 Activity 返回结果时),或者为其安排新任务。 • 在 Android 5.0(API 级别 21)及更高版本中,您可以使用 JobScheduler 类来调度操作。对于早期 Android 版本,您可以通过向 startService() 传递 Intent 来启动服务(或对执行中的服务下达新指令)。您也可通过向将 bindService() 传递 Intent 来绑定到该服务。 • 您可以通过向 sendBroadcast()、sendOrderedBroadcast() 或 sendStickyBroadcast() 等方法传递 Intent 来发起广播。 • 您可以通过在 ContentResolver 上调用 query(),对内容提供程序执行查询。 如需了解有关 Intent 用法的详细信息,请参阅 Intent 和 Intent 过滤器文档。以下文档将为您详细介绍如何启动特定组件:Activity、服务、BroadcastReceiver 和内容提供程序。

问问小秘 2020-03-03 09:47:38 0 浏览量 回答数 0

问题

使用 ASM 实现 Java 语言的“多重继承”:报错

kun坤 2020-06-06 15:29:41 0 浏览量 回答数 1

问题

基于 Laravel 开发 ThinkSNS中前端的抉择【研发日记】

ThinkSNS 2019-12-01 21:25:23 2422 浏览量 回答数 0

问题

Java技术1000问(3)【精品问答】

问问小秘 2020-06-02 14:27:10 42 浏览量 回答数 1

回答

本文以 Nacos 配置管理的 Demo 应用为例,介绍如何在本地开发、调试 Spring Cloud 应用,实现 Spring Cloud Alibaba Nacos Config 实现配置管理,并通过 SAE 进行配置管理与推送。 背景信息 在开发 Spring Cloud 应用时,您可以在本地使用 Nacos (https://nacos.io) 实现应用的配置管理。由于 SAE 集成了 Nacos 的应用配置管理 ACM 的开源版本,在应用部署到 SAE 后,您可以通过 SAE 对应用进行配置的管理和推送。 本文以 Spring Cloud 应用开发过程为例,使用 Spring Cloud Alibaba Nacos Config 实现配置管理。您也可以下载该应用示例的 Demo nacos-config-example。 说明 Spring Cloud Alibaba Nacos Config 对 Nacos 与 Spring Cloud 框架的进行了整合,支持 Spring Cloud 的配置注入规范。 准备工作 在开始开发前,请确保您已经完成以下工作: 下载 Maven 并设置环境变量。 下载最新版本的 Nacos Server。 启动 Nacos Server。 解压下载的 Nacos Server 压缩包 进入nacos/bin目录,启动 Nacos Server。 Linux/Unix/Mac 系统:执行命令sh startup.sh -m standalone。 Windows 系统:双击执行startup.cmd文件。 在本地 Nacos Server 控制台新建配置。 登录本地 Nacos Server 控制台(用户名和密码默认同为 nacos)。 在左侧导航栏中单击配置列表,在配置列表页面右上角单击新建配置图标增加图标。 在新建配置页面填入以下信息,单击并发布。 Data ID: nacos-config-example.properties Group: DEFAULT_GROUP 配置内容: test.name=nacos-config-test 使用 Nacos Config 实现配置管理 创建一个 Maven 工程,命名为 nacos-config-example。 在pom.xml文件中添加依赖。 以 Spring Boot 2.1.4.RELEASE 和 Spring Cloud Greenwich.SR1 为例。 org.springframework.boot spring-boot-starter-parent 2.1.4.RELEASE org.springframework.boot spring-boot-starter-web com.alibaba.cloud spring-cloud-starter-alibaba-nacos-config 2.1.1.RELEASE org.springframework.cloud spring-cloud-dependencies Greenwich.SR1 pom import org.springframework.boot spring-boot-maven-plugin 示例中使用的版本为 Spring Cloud Greenwich ,对应 Spring Cloud Alibaba 版本为 2.1.1.RELEASE。 如果使用 Spring Cloud Finchley 版本,对应 Spring Cloud Alibaba 版本为 2.0.1.RELEASE。 如果使用 Spring Cloud Edgware 版本,对应 Spring Cloud Alibaba 版本为 1.5.1.RELEASE。 说明 Spring Cloud Edgware 版本的生命周期已结束,不推荐使用这个版本开发应用。 在src\main\java下创建 Packagecom.aliware.edas。 在 Packagecom.aliware.edas中创建nacos-config-example 的启动类 NacosConfigExampleApplication。 import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class NacosConfigExampleApplication { public static void main(String[] args) { SpringApplication.run(NacosConfigExampleApplication.class, args); } } 在 Packagecom.aliware.edas中创建一个简单的 ControllerEchoController,自动注入一个属性userName,且通过@Value注解指定从配置中取 Key 为test.name的值。 import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RefreshScope public class EchoController { @Value("${test.name}") private String userName; @RequestMapping(value = "/") public String echo() { return userName; } } 在src\main\resources路径下创建配置文件bootstrap.properties,在bootstrap.properties中添加如下配置,指定 Nacos Server 的地址。 其中127.0.0.1:8848为 Nacos Server 的地址,18081为服务端口。 如果您的 Nacos Server 部署在另外一台机器,则需要修改成对应的 IP 和端口。如果有其它需求,可以参照配置项参考在bootstrap.properties文件中增加配置。 spring.application.name=nacos-config-example server.port=18081 spring.cloud.nacos.config.server-addr=127.0.0.1:8848 执行NacosConfigExampleApplication中的 main 函数,启动应用。 部署到 SAE 在本地完成应用的开发和测试后,将应用程序部署到 SAE,详细步骤请参见应用部署概述。 说明 SAE 配置管理中心提供了正式商用版本 Nacos Server。当您将应用部署到 SAE 的时候,SAE 会通过优先级更高的方式去设置 Nacos Server 服务端地址和服务端口,以及 namespace、access-key、secret-key、context-path 信息。您无需进行任何额外的配置,原有的配置内容可以选择保留或删除。 如果您是初次在 SAE 控制台进行部署。如果使用 JAR 包部署,在创建应用时应用运行环境 须选 标准 Java 应用运行环境。SAE-JAR方式部署-应用运行环境配置 在部署应用前,请使用 SAE 的配置管理功能,创建与本地 Nacos Server 中相同的应用配置。 登录 SAE 控制台。 在左侧导航栏中选择配置管理。 在配置管理页面选择地域和命名空间,单击页面右侧 添加按钮。 在新建配置页面中设置 Data ID、Group 和 配置内容,配置完成后单击发布。 Data ID: nacos-config-example.properties Group:DEFAULT_GROUP 配置内容: test.name=nacos-config-test 结果验证 部署完成后,可以通过查看日志确认应用是否启动成功。 执行命令curl http://<应用实例 IP>:<服务端口>,如curl http://192.168.0.34:8080 查看是否返回配置内容 nacos-config-test。 在 SAE 控制台将原有配置内容修改为 nacos-config-test2,再执行命令curl http://<应用实例 IP>:<服务端口>,如curl http://192.168.0.34:8080,查看是否返回变更后的配置内容 nacos-config-test2。 配置项参考 如果有其它需求,可以参照下表在bootstrap.properties文件中增加配置。 配置项 key 默认值 说明 服务端地址 spring.cloud.nacos.config.server-addr 无 无 DataId 前缀 spring.cloud.nacos.config.prefix ${spring.application.name} Data ID 的前缀 Group spring.cloud.nacos.config.group DEFAULT_GROUP Data ID 后缀及内容文件格式 spring.cloud.nacos.config.file-extension properties Data ID 的后缀,同时也是配置内容的文件格式,默认是 properties,支持 yaml 和 yml。 配置内容的编码方式 spring.cloud.nacos.config.encode UTF-8 配置的编码 获取配置的超时时间 spring.cloud.nacos.config.timeout 3000 单位为 ms 配置的命名空间 spring.cloud.nacos.config.namespace 常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源隔离等。 相对路径 spring.cloud.nacos.config.context-path 服务端 API 的相对路径 接入点 spring.cloud.nacos.config.endpoint UTF-8 地域的某个服务的入口域名,通过此域名可以动态地拿到服务端地址。 是否开启监听和自动刷新 spring.cloud.nacos.config.refresh.enabled true 默认为 true,不需要修改。 更多配置项,请参考开源版本的 Spring Cloud Alibaba Nacos Config 文档。

1934890530796658 2020-03-27 11:57:17 0 浏览量 回答数 0

回答

除了可以使用传统的 XML 配置方式开发 Dubbo 应用,还可以使用 Spring Boot 开发 Dubbo 应用,特别对于 Java 技术薄弱和 Maven 经验少,且又不熟悉 Dubbo 框架的开发者更为适合。本文以全新开发过程,向您展示如何使用 Spring Boot 开发 Dubbo 应用,并使用 SAE 服务注册中心实现服务注册与发现。 前提条件 下载 Maven并设置环境变量。 下载最新版本的 Nacos Server。 启动 Nacos Server。 解压下载的 Nacos Server 压缩包 进入nacos/bin目录,启动 Nacos Server。 Linux/Unix/Mac 系统:执行命令sh startup.sh -m standalone。 Windows 系统:双击执行startup.cmd文件。 在本地开发应用时,可以使用 Alibaba Cloud Toolkit 插件实现本地应用和部署在 EDAS 中的应用的相互调用,即端云互联,而无需搭建 VPN,帮助您提升开发效率。详情请参见为 EDAS 应用设置端云互联。 为什么使用 Spring Boot 开发 Dubbo 应用 Spring Boot 简化了微服务应用的配置和部署,同时 Nacos 又同时提供了服务注册发现和配置管理功能,两者结合的方式能够帮助您快速搭建基于 Spring 的 Dubbo 服务,相比 xml 的开发方式,大幅提升开发效率。 全新场景使用 Spring Boot 开发 Dubbo 应用有两种主要的方式: 使用 xml 开发。 使用 Spring Boot 的注解方式开发。 使用 xml 方式请参考将 Dubbo 应用托管到 SAE。文本档介绍如何使用 Spring Boot 的注解方式开发 Dubbo 服务。 视频教程 本视频仅介绍使用 Spring Boot 开发 Dubbo 应用,部署部分请参见在SAE控制台部署应用。 示例工程 您可以按照本文的逐步搭建工程,也可以选择直接下载本文对应的示例工程,或者使用 Git 来 clone: git clone https://github.com/aliyun/alibabacloud-microservice-demo.git 该项目包含了众多了示例工程,本文对应的示例工程位于 alibabacloud-microservice-demo/microservice-doc-demo/dubbo-samples-spring-boot。 创建服务提供者 创建命名为spring-boot-dubbo-provider的 Maven 工程。 在pom.xml文件中添加所需的依赖。 这里以 Spring Boot 2.0.6.RELEASE 为例。 org.springframework.boot spring-boot-dependencies 2.0.6.RELEASE pom import org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-actuator org.apache.dubbo dubbo-spring-boot-starter 2.7.3 com.alibaba.nacos nacos-client 1.1.1 开发 Dubbo 服务提供者。 Dubbo 中服务都是以接口的形式提供的。 在src/main/java路径下创建一个 package com.alibaba.edas.boot。 在com.alibaba.edas.boot下创建一个接口(interface) IHelloService,里面包含一个 SayHello 方法。 package com.alibaba.edas.boot; public interface IHelloService { String sayHello(String str); } 在com.alibaba.edas.boot下创建一个类IHelloServiceImpl,实现此接口。 package com.alibaba.edas.boot; import com.alibaba.dubbo.config.annotation.Service; @Service public class IHelloServiceImpl implements IHelloService { public String sayHello(String name) { return "Hello, " + name + " (from Dubbo with Spring Boot)"; } } 说明 这里的 Service 注解是 Dubbo 提供的一个注解类,类的全名称为:com.alibaba.dubbo.config.annotation.Service 。 配置 Dubbo 服务。 在 src/main/resources路径下创建application.properties或application.yaml文件并打开。 在application.properties或application.yaml中添加如下配置。 Base packages to scan Dubbo Components (e.g @Service , @Reference) dubbo.scan.basePackages=com.alibaba.edas.boot dubbo.application.name=dubbo-provider-demo dubbo.registry.address=nacos://127.0.0.1:8848 说明 以上三个配置没有默认值,必须要给出具体的配置。 dubbo.scan.basePackages的值是开发的代码中含有com.alibaba.dubbo.config.annotation.Service和com.alibaba.dubbo.config.annotation.Reference注解所在的包。多个包之间用逗号隔开。 dubbo.registry.address的值前缀必须以 nacos:// 开头,后面的 IP 地址和端口指的是 Nacos Server 的地址。代码示例中为本地地址,如果您将 Nacos Server 部署在其它机器上,请修改为实际的 IP 地址。 开发并启动 Spring Boot 入口类DubboProvider。 package com.alibaba.edas.boot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class DubboProvider { public static void main(String[] args) { SpringApplication.run(DubboProvider.class, args); } } 登录 Nacos 控制台 http://127.0.0.1:8848,在左侧导航栏中单击服务列表 ,查看提供者列表。 可以看到服务提供者里已经包含了com.alibaba.edas.boot.IHelloService,且可以查询该服务的服务分组和提供者 IP。 创建服务消费者 创建一个 Maven 工程,命名为spring-boot-dubbo-consumer。 在pom.xml文件中添加相关依赖。 这里以 Spring Boot 2.0.6.RELEASE 为例。 org.springframework.boot spring-boot-dependencies 2.0.6.RELEASE pom import org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-actuator org.apache.dubbo dubbo-spring-boot-starter 2.7.3 com.alibaba.nacos nacos-client 1.1.1 如果您需要选择使用 Spring Boot 1.x 的版本,请使用 Spring Boot 1.5.x 版本,对应的 com.alibaba.boot:dubbo-spring-boot-starter 版本为 0.1.0。 说明 Spring Boot 1.x 版本的生命周期即将在 2019 年 8 月 结束,推荐使用新版本开发您的应用。 开发 Dubbo 消费者。 在src/main/java路径下创建 package com.alibaba.edas.boot。 在com.alibaba.edas.boot下创建一个接口(interface) IHelloService,里面包含一个 SayHello 方法。 package com.alibaba.edas.boot; public interface IHelloService { String sayHello(String str); } 开发 Dubbo 服务调用。 例如需要在 Controller 中调用一次远程 Dubbo 服务,开发的代码如下所示。 package com.alibaba.edas.boot; import com.alibaba.dubbo.config.annotation.Reference; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class DemoConsumerController { @Reference private IHelloService demoService; @RequestMapping("/sayHello/{name}") public String sayHello(@PathVariable String name) { return demoService.sayHello(name); } } 说明 这里的 Reference 注解是 com.alibaba.dubbo.config.annotation.Reference 。 在application.properties/application.yaml配置文件中新增以下配置。 dubbo.application.name=dubbo-consumer-demo dubbo.registry.address=nacos://127.0.0.1:8848 说明 以上两个配置没有默认值,必须要给出具体的配置。 dubbo.registry.address的值前缀必须以 nacos:// 开头,后面的 IP 地址和端口为 Nacos Server 的地址。代码示例中为本地地址,如果您将 Nacos Server 部署在其它机器上,请修改为实际的 IP 地址。 开发并启动 Spring Boot 入口类DubboConsumer。 package com.alibaba.edas.boot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class DubboConsumer { public static void main(String[] args) { SpringApplication.run(DubboConsumer.class, args); } } 登录 Nacos 控制台 http://127.0.0.1:8848,在左侧导航栏中单击服务列表,再在服务列表页面单击调用者列表页签,查看调用者列表。 可以看到包含了com.alibaba.edas.boot.IHelloService,且可以查看该服务的服务分组和调用者 IP。 结果验证 curl http://localhost:8080/sayHello/EDAS Hello, EDAS (from Dubbo with Spring Boot) 部署到 SAE 本地使用 Nacos 作为注册中心的应用,可以直接部署到 SAE 中,无需做任何修改,注册中心会被自动替换为 SAE上的注册中心。 您可以根据实际需求选择部署途径(控制台或工具),详情请参见应用部署概述。 使用控制台部署前,请参见如下操作将应用程序编译为可运行的JAR包、WAR包。 在pom.xml文件中添加以下打包插件的配置。 Provider org.springframework.boot spring-boot-maven-plugin repackage spring-boot com.alibaba.edas.boot.DubboProvider Consumer org.springframework.boot spring-boot-maven-plugin repackage spring-boot com.alibaba.edas.boot.DubboConsumer 执行 mvn clean package 将本地的程序打成 JAR 包。 更多信息 除 Spring Boot 外,还可以通过 XML 的方式开发 Dubbo 微服务应用,详情请参见将 Dubbo 应用托管到 SAE。 应用部署到 SAE 后,您可以对应用进行管理、绑定 SLB 等操作。 应用部署 应用管理 监控管理 日志管理

1934890530796658 2020-03-27 12:50:55 0 浏览量 回答数 0

问题

服务器运维系列教程(二):服务搭建---Windows篇

千鸟 2019-12-01 21:53:28 10096 浏览量 回答数 2

问题

MaxCompute用户指南:处理非结构化数据:访问 OSS 非结构化数据

行者武松 2019-12-01 22:05:18 1382 浏览量 回答数 0
阿里云大学 云服务器ECS com域名 网站域名whois查询 开发者平台 小程序定制 小程序开发 国内短信套餐包 开发者技术与产品 云数据库 图像识别 开发者问答 阿里云建站 阿里云备案 云市场 万网 阿里云帮助文档 免费套餐 开发者工具 企业信息查询 小程序开发制作 视频内容分析 企业网站制作 视频集锦 代理记账服务 2020阿里巴巴研发效能峰会 企业建站模板 云效成长地图 高端建站 阿里云双十一主会场 阿里云双十一新人会场 1024程序员加油包 阿里云双十一拼团会场 场景化解决方案 阿里云双十一直播大厅