17
回答
@eechen来来,哥给你展示什么叫“优雅”

@eechen总是在与自己无关的问题乱插一脚,要么推销php,要么攻击别的语言,比如:https://www.oschina.net/question/3188325_2215860

本人对php没什么偏见,而且我们公司的oa就是用php开发的。在我看来“优雅”就是简单直观,最近刚好用python搭建公司的微服务框架,现在用它来展示一下python所谓的”优雅“是怎么样的。关于微服务框架,我不想说太多,只说两点:

1.横向扩展能力。哪一个微服务压力大就多运行几个实例就行了,结合容器技术,可以实现自动伸缩部署,压力大时多启动几个实例,压力低时自动停止几个实例;

2.接口化,服务化有利于代码复用,多端共用一个后台。比如我们的老系统,很多地方都要选择商品,每个地方都自己去数据库查,再比如下订单,要上移动端,那只能重新看下订单往哪些表插数据,如果用微服务架构则不会有这些问题。
用我们的框架写一个微服务的例子如下:

from microservice import api,start

@api.arg('name','姓名',type=api.String(strip=True),required=True)
@api.arg('age','年龄',type=api.Integer(min=0,max=120),required=True)
@api.arg('hobby','爱好',type=api.List())
@api.arg('memo')
@api.func
def test(args):
    '''
    测试函数1
    返回值:
        xxx
    '''
    #通过args.xx取得参数,得到的参数都是干净的了
    return 'hello,%s' % args.name


@api.arg('x',type=api.Integer(),required=True)
@api.arg('y',type=api.Integer(),required=True)
@api.func
def add(args):
    '''
    两数相加
    '''
    return args.x+args.y

@api.func
def test_add(args):
    '''
    测试add
    '''
    x=100
    y=200
    r=api.call('first_service.add',x=x,y=y)
    return '%s+%s=%s' % (x,y,r)


if __name__=='__main__':
    start(
        name='first_service',
        description='第一个微服务'
    )



然后,可以在python项目中调用代码如下,不用关心服务在哪台机上运行:

from microservice import api

r=api.call('first_service.add',x=1,y=2)
print(r)



也可以通过http接口调用:

curl http://入口服务器/call/first_service.add?x=1&y=2



后台可以看到微服务运行情况,比如下面看到frist_service这个服务运行吧两个实例在dingtalk.bjh和wei-PC两台机上:

点击”文档“可以看到first_service服务提供的接口文档,文档都是自动生成的:

点”在线测试“可以测试接口:

@eechen让你用php写一个微服务框架,你能包装得比这个更简单直观吗?

举报
wei2011
发帖于2年前 17回/1K+阅
共有17个评论 最后回答: 2年前
这个和语言有什么关系?
--- 共有 1 条评论 ---
wei2011我没说和语言有什么关系啊,我只是展示了python的优雅简单,如果你用php写得更加简单,可以展示一下学习学习 2年前 回复
<?php
/**
 * Unit testing class to support reports
 * All the public function start with test will be evaluated within Class which extends gunit
 * Once evaluation return true the test passed
 * 
 * And the Page could be rendered as output 
 *
 * @author anthony chen
 * @version 1.0
 */
class Gunit{
	/**
	 * Script time execution function
	 */
	public function microt(){
		list($usec, $sec) = explode(" ", microtime());
		return ((float)$usec + (float)$sec);
	}

	/**
	 * Run all tests and draw a table with the results
	 *
	 * @param String $page, UTL page to rend, default gunit/text for cli and gunit/html for page
	 * @output String , the standard output buffer will be populated into notes in report
	 * @return String 
	 */
	public function run($page = NULL){
		if($page == NULL){
			if(Pexcel::$is_cli == false){
				$_page = New UTL('gunit/html','views','.shtml',array('{','}'),SYSPATH);
			}else{
				$_page = New UTL('gunit/text','views','.shtml',array('{','}'),SYSPATH);
			}
		}else{
			$_page = New UTL($page);
		}

		$_successed = 0;
		$results = array();
		$c = get_class( $this );
		$_page->c = $c;

		$functions = get_class_methods( $c );
		foreach ( $functions as $function ){
			if( strpos( $function, 'test' ) !== false ){
	 			ob_start();
				$time_start = $this->microt();
				$result = call_user_func( array( $c, $function ) );
				$time_end = $this->microt();
				$r['time'] = substr( (string) ( $time_end - $time_start ), 0, 6 );
				$r['function'] = $function;
				$r['status'] = ( $result === true ) ? true : false;
				$r['note'] =  ob_get_contents();
				if( $result === true )
					$_successed ++;
				$results[] = $r;
	    		ob_end_clean();
			}
		}
		$_page->results = $results;
		$_page->total = count($results);
		$_page->successed = $_successed;
		$_page->failed = $_page->total - $_successed;
		return $_page;
	}
}



无知不可怕,可怕的是拿出来秀
--- 共有 5 条评论 ---
wei2011回复 @leo108 : 我说的这个是指服务发现,自动负载,如果的框架没有这个功能说明不是微服务框架,只是一般的restful框架而已。我这服务不需要部署,直接运行就自动发现服务加入负载,以后会实现自动申缩部署 2年前 回复
leo108回复 @wei2011 : 建议楼主真正用php开发过真正的项目之后再来评判,这样就不会说出“同一个服务运行在多台主机能自动负载么”这种搞笑的话了 2年前 回复
wei2011回复 @leo108 : 本来是不爽eechen才发这个的,你来秀优越。说实在,你那套东西真没看出什么亮点,参数规则繁复麻烦;同一个服务运行在多台主机能自动负载么?服务之间调用用http,返回的像日期这种类型之类还要自己转换?真不想吐糟太多,有点技术的公司都不会用你这套东西 2年前 回复
leo108回复 @wei2011 : http://www.phalapi.net/ 2年前 回复
wei2011你也来秀一下 2年前 回复

对比一下dubbo,有如下的优势和劣势:

优势:

1. 日志审计

2. 接口文档

3. annotation直接能启动服务,但是算是侵入式的框架。


劣势:

1. 写死了必须http服务,目前的rpc框架一般支持三种及以上的协议,例如http,protobuf,hessian等。

2. 只看接口,不能指定failover,failfast等各种fail的处理。

3. 不分机房等。

总的来说,是个很好的rpc框架。


说白了,你的代码只是说明你们的微服务框架是个很好的rpc框架,

并不能说。

--- 共有 1 条评论 ---
wei2011我这东西是用了不到一周的时候弄出来的,不要拿来和已经完善的框架比 2年前 回复
def test(api):
    '''
    测试函数1
    返回值:
        xxx
    '''
    api.arg('name','姓名',type=api.String(strip=True),required=True)
    api.arg('age','年龄',type=api.Integer(min=0,max=120),required=True)
    api.arg('hobby','爱好',type=api.List())
    api.arg('memo')
    args = api.render()
    #通过args.xx取得参数,得到的参数都是干净的了
    return 'hello,%s' % args.name

你的代码和我上面这种也没什么区别对吧,无论从可读性还是行数还是什么。

那我转换过之后,是不是什么语言实现都能打到这种程度了?

所以这个不足以说明Python语言有多优雅,只不过搞了下AOP概念而已。


--- 共有 4 条评论 ---
東條・スペンサー・咲回复 @乌龟壳 : 生成文档有的时候还真的挺重要的。Qt还有类似的软件和库在生成API文档的时候,会直接把文档注释在代码中,然后使用类似doxygen这样的工具生成文档。 2年前 回复
乌龟壳回复 @wei2011 : 也不是生成不了,遍历所有参数是api的函数,然后传入生成文档的api对象,执行到render就直接返回文档。不过这样看是没有现成的工具支持的,但也不是做不到。话说生成文档这是什么需求,一般有公司拿着源代码不用还生成一份文档? 2年前 回复
乌龟壳回复 @wei2011 : 我这样写顶多运行时生成文档,直接拿着源代码生成不了。不过除了生成文档,也没别的优势了吧? 2年前 回复
wei2011你这样给我自动生成文档一下 2年前 回复

py是脚本,不仅仅局限在web应用,其他能干的他只要有库就能干。

php是主要应用于web的语言。

对比效率就免了,淘宝也是php的,这个例子就够了,需求看场景


看了https://www.oschina.net/question/3188325_2215860 重点不在内容在留言,笑死我了。

程序员何必为难程序员

微服务 长见识了,多贴贴这种涨知识的帖子很不错


--- 共有 1 条评论 ---
hylent6 2年前 回复

引用来自“小耶果”的评论

任何"优雅"的表面下必定有"肮脏"的实现.没办法,这是计算机的本质决定的.

确实如此, 楼主的代码看不出python的优雅, 同样类型的代码换个语言都可以完成, 无非的多几行少几行的问题. 

表面下封装的代码多少与表面上需要写的代码多少是成正比的.


顶部